<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="generator" content="VNote">

    <title>8_访问外部SQL数据库</title>
    <link rel="icon" href="https://github.com/tamlok/vnote/raw/master/src/resources/icons/vnote.ico">

    <style type="text/css">
    /* STYLE_GLOBAL_PLACE_HOLDER */
    </style>

    <style type="text/css">
    *,
*::before,
*::after {
  box-sizing: border-box;
}

.container-fluid {
    width: 100%;
    padding-right: 15px;
    padding-left: 15px;
    margin-right: auto;
    margin-left: auto;
}

.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto {
    position: relative;
    width: 100%;
    min-height: 1px;
    padding-right: 15px;
    padding-left: 15px;
}

.col-12 {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 100%;
    flex: 0 0 100%;
    max-width: 100%;
}

@media (min-width: 768px) {
    .col-md-3 {
        -webkit-box-flex: 0;
        -ms-flex: 0 0 25%;
        flex: 0 0 25%;
        max-width: 25%;
    }
}

@media (min-width: 768px) {
    .col-md-9 {
        -webkit-box-flex: 0;
        -ms-flex: 0 0 75%;
        flex: 0 0 75%;
        max-width: 75%;
    }
}

@media (min-width: 1200px) {
    .col-xl-2 {
        -webkit-box-flex: 0;
        -ms-flex: 0 0 16.666667%;
        flex: 0 0 16.666667%;
        max-width: 16.666667%;
    }
}

@media (min-width: 1200px) {
    .col-xl-10 {
        -webkit-box-flex: 0;
        -ms-flex: 0 0 83.333333%;
        flex: 0 0 83.333333%;
        max-width: 83.333333%;
    }
}

@media (min-width: 768px) {
    .pt-md-3, .py-md-3 {
        padding-top: 1rem!important;
    }
}

@media (min-width: 768px) {
    .pb-md-3, .py-md-3 {
        padding-bottom: 1rem!important;
    }
}

@media (min-width: 768px) {
    .pl-md-5, .px-md-5 {
        padding-left: 3rem!important;
    }
}

.d-none {
    display: none!important;
}

@media (min-width: 1200px) {
    .d-xl-block {
        display: block!important;
    }
}

@media (min-width: 768px) {
    .d-md-block {
        display: block!important;
    }
}

.bd-content {
    -webkit-box-ordinal-group: 1;
    -ms-flex-order: 0;
    order: 0;
}

.bd-toc {
    position: -webkit-sticky;
    position: sticky;
    top: 4rem;
    height: calc(100vh - 10rem);
    overflow-y: auto;
}

.bd-toc {
    -webkit-box-ordinal-group: 2;
    -ms-flex-order: 1;
    order: 1;
    padding-top: 1.5rem;
    padding-bottom: 1.5rem;
    font-size: .875rem;
}

.section-nav {
    padding-left: 0;
}

.section-nav ul {
    font-size: .875rem;
    list-style-type: none;
}

.section-nav li {
    font-size: .875rem;
}

.section-nav a {
    color: inherit !important;
}

.row {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    margin-right: -15px;
    margin-left: -15px;
}

@media (min-width: 1200px) {
    .flex-xl-nowrap {
        flex-wrap: nowrap !important;
    }
}

#floating-button {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    background: #00897B;
    position: fixed;
    top: .5rem;
    right: .5rem;
    cursor: pointer;
    box-shadow: 0px 2px 5px #666;
}

#floating-button .more {
    color: #F5F5F5;
    position: absolute;
    top: 0;
    display: block;
    bottom: 0;
    left: 0;
    right: 0;
    text-align: center;
    padding: 0;
    margin: 0;
    line-height: 2.5rem;
    font-size: 2rem;
    font-family: 'monospace';
    font-weight: 300;
}

.hide-none {
    display: none !important;
}

.col-expand {
    -webkit-box-flex: 0;
    -ms-flex: 0 0 100% !important;
    flex: 0 0 100% !important;
    max-width: 100% !important;
    padding-right: 3rem !important;
}

.outline-bold {
    font-weight: bolder !important;
}

@media print {
    #floating-button {
        display: none !important;
    }
}

    @keyframes flash { 
  0% { color: rgb(128, 203, 196); }
  10% { color: rgb(0, 137, 123); }
  40% { color: rgb(0, 137, 123); }
  50% { color: rgb(128, 203, 196); }
  60% { color: rgb(0, 137, 123); }
  90% { color: rgb(0, 137, 123); }
}
.highlighted-anchor { animation: flash 1s; }
div.mark-rect { background: transparent; border: 5px solid rgb(87, 104, 196); border-radius: 2px; position: absolute; }
#vnote-footer { width: 100%; text-align: center; opacity: 0.2; margin-top: 3rem; }
#vnote-footer p { font-size: 0.8rem; }
#vnote-footer a { color: inherit !important; }
x-eqs { display: flex; flex-direction: row; align-content: space-between; align-items: center; }
x-eqs > x-eqn { width: 100%; margin-left: 3rem; }
x-eqs > span { text-align: right; }
.view-image, .view-svg { transition: 0.3s; }
.modal-box { display: none; position: fixed; z-index: 1000; padding-top: 50px; left: 0px; top: 0px; width: 100%; height: 100%; overflow: hidden; background-color: rgba(68, 68, 68, 0.952941); }
.modal-content { margin: auto; display: block; width: auto; height: auto; cursor: move; }
.modal-content { animation-name: zoom; animation-duration: 0.6s; }
@-webkit-keyframes zoom { 
  0% { transform: scale(0); }
  100% { transform: scale(1); }
}
@keyframes zoom { 
  0% { transform: scale(0); }
  100% { transform: scale(1); }
}
span.modal-close { position: absolute; z-index: 1000; top: 15px; right: 35px; color: rgb(218, 218, 218); font-size: 40px; font-weight: bold; transition: 0.3s; }
span.modal-close:hover, span.modal-close:focus { color: rgb(238, 238, 238); text-decoration: none; cursor: pointer; }
@media print {
  pre, pre code, td.hljs-ln-code { white-space: pre-wrap !important; word-break: break-all !important; }
  code, a { word-break: break-all !important; }
  div.flowchart-diagram, div.mermaid-diagram, div.plantuml-diagram { overflow: hidden !important; }
  img { max-width: 100% !important; height: auto !important; }
  #vnote-footer { display: none !important; }
}
.alert { position: relative; padding: 0.75rem 1.25rem; margin-bottom: 1rem; border: 1px solid transparent; border-radius: 0.25rem; }
.alert-primary { color: rgb(0, 64, 133); background-color: rgb(204, 229, 255); border-color: rgb(184, 218, 255); }
.alert-secondary { color: rgb(56, 61, 65); background-color: rgb(226, 227, 229); border-color: rgb(214, 216, 219); }
.alert-success { color: rgb(21, 87, 36); background-color: rgb(212, 237, 218); border-color: rgb(195, 230, 203); }
.alert-info { color: rgb(12, 84, 96); background-color: rgb(209, 236, 241); border-color: rgb(190, 229, 235); }
.alert-warning { color: rgb(133, 100, 4); background-color: rgb(255, 243, 205); border-color: rgb(255, 238, 186); }
.alert-danger { color: rgb(114, 28, 36); background-color: rgb(248, 215, 218); border-color: rgb(245, 198, 203); }
.alert-light { color: rgb(129, 129, 130); background-color: rgb(254, 254, 254); border-color: rgb(253, 253, 254); }
.alert-dark { color: rgb(27, 30, 33); background-color: rgb(214, 216, 217); border-color: rgb(198, 200, 202); }
.vnote-anchor { font-weight: 400; color: rgba(0, 123, 255, 0.498039); transition: color 0.16s linear; padding-left: 0.375em; -webkit-font-smoothing: antialiased; text-decoration: none; opacity: 0; }
.vnote-anchor:hover { color: rgb(0, 123, 255); text-decoration: none; opacity: 1; }
.vnote-anchor::after { content: attr(data-anchor-icon); }
.vnote-btn { position: relative; display: inline-block; padding: 6px 12px; font-size: 13px; font-weight: 700; line-height: 20px; white-space: nowrap; vertical-align: middle; cursor: pointer; border: none; user-select: none; -webkit-appearance: none; }
.vnote-copy-clipboard-btn { transition: opacity 0.3s ease-in-out; opacity: 0; padding: 2px 6px; position: absolute; top: 5px; right: 5px; }
pre:hover .vnote-copy-clipboard-btn { opacity: 1; }
pre.vnote-snippet { position: relative; }
body { margin: 0px auto; font-family: "Segoe UI", Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", 冬青黑体, "Microsoft YaHei", 微软雅黑, "Microsoft YaHei UI", "WenQuanYi Micro Hei", 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, "Liberation Sans", "Droid Sans", NSimSun, 新宋体, SimSun, 宋体; color: rgb(34, 34, 34); line-height: 1.5; padding: 15px; background: rgb(238, 238, 238); font-size: 16px; }
h1, h2, h3, h4, h5, h6 { color: rgb(34, 34, 34); font-weight: bold; margin-top: 20px; margin-bottom: 10px; padding: 0px; }
p { padding: 0px; margin-top: 16px; margin-bottom: 16px; }
h1 { font-size: 26px; }
h2 { font-size: 24px; }
h3 { font-size: 22px; }
h4 { font-size: 20px; }
h5 { font-size: 19px; }
h6 { font-size: 18px; }
a { color: rgb(0, 153, 255); margin: 0px; padding: 0px; vertical-align: baseline; text-decoration: none; word-break: break-word; }
a:hover { text-decoration: underline; color: rgb(255, 102, 0); }
a:visited { color: purple; }
ul, ol { padding: 0px 0px 0px 24px; }
li { line-height: 24px; }
li ul, li ol { margin-left: 16px; }
p, ul, ol { font-size: 16px; line-height: 24px; }
pre { display: block; overflow-y: hidden; overflow-x: auto; tab-size: 4; }
code { font-family: Consolas, Monaco, monospace, Courier; color: rgb(142, 36, 170); word-break: break-word; }
pre code { display: block; overflow-x: auto; padding: 0.5em; color: rgb(34, 34, 34); background-color: rgb(224, 224, 224); border-left: 0.5em solid rgb(0, 137, 123); line-height: 1.5; font-family: Consolas, Monaco, monospace, Courier; white-space: pre; tab-size: 4; }
pre code.markdown-metadata { border-left: 0.5em solid rgb(128, 203, 196); }
aside { display: block; float: right; width: 390px; }
blockquote { color: rgb(102, 102, 102); border-left: 0.5em solid rgb(122, 122, 122); padding: 0px 1em; margin-left: 0px; }
blockquote p { color: rgb(102, 102, 102); }
hr { display: block; text-align: left; margin: 1em 0px; border: none; height: 2px; background: rgb(153, 153, 153); }
table { padding: 0px; margin: 1rem 0.5rem; border-collapse: collapse; }
table tr { border-top: 2px solid rgb(204, 204, 204); background-color: white; margin: 0px; padding: 0px; }
table tr:nth-child(2n) { background-color: rgb(248, 248, 248); }
table tr th { font-weight: bold; border: 2px solid rgb(204, 204, 204); margin: 0px; padding: 6px 13px; }
table tr td { border: 2px solid rgb(204, 204, 204); margin: 0px; padding: 6px 13px; }
table tr th :first-child, table tr td :first-child { margin-top: 0px; }
table tr th :last-child, table tr td :last-child { margin-bottom: 0px; }
div.mermaid-diagram { margin: 16px 0px; overflow-y: hidden; }
div.flowchart-diagram { padding: 0px 5px; margin: 16px 0px; width: fit-content; overflow: hidden; }
div.wavedrom-diagram { padding: 0px 5px; margin: 16px 0px; width: fit-content; overflow: hidden; }
div.plantuml-diagram { padding: 5px 5px 0px; margin: 16px 0px; width: fit-content; overflow: hidden; }
.img-package { text-align: center; }
img.img-center { display: block; margin-left: auto; margin-right: auto; }
span.img-caption { min-width: 20%; max-width: 80%; display: inline-block; padding: 10px; margin: 0px auto; border-bottom: 1px solid rgb(192, 192, 192); color: rgb(108, 108, 108); text-align: center; line-height: 1.5; }
.emoji_zero, .emoji_one, .emoji_two, .emoji_three, .emoji_four, .emoji_five, .emoji_six, .emoji_seven, .emoji_eight, .emoji_nine { margin-left: 5px; margin-right: 8px; }
div.preview-hint { opacity: 0.5; margin-top: 30%; margin-bottom: 30%; align-items: center; display: flex; flex-direction: column; justify-content: center; }
table.hljs-ln tr { border: none; background-color: transparent; }
table.hljs-ln tr td { border: none; background-color: transparent; }
table.hljs-ln tr td.hljs-ln-numbers { user-select: none; text-align: center; color: rgb(170, 170, 170); border-right: 1px solid rgb(204, 204, 204); vertical-align: top; padding-right: 5px; white-space: nowrap; }
table.hljs-ln tr td.hljs-ln-code { padding-left: 10px; }
::-webkit-scrollbar { background-color: rgb(234, 234, 234); width: 14px; height: 14px; border: none; }
::-webkit-scrollbar-corner { background-color: rgb(234, 234, 234); }
::-webkit-scrollbar-button { height: 14px; width: 14px; background-color: rgb(234, 234, 234); }
::-webkit-scrollbar-button:hover { background-color: rgb(208, 208, 208); }
::-webkit-scrollbar-button:active { background-color: rgb(178, 178, 178); }
::-webkit-scrollbar-track { background-color: rgb(234, 234, 234); }
::-webkit-scrollbar-thumb { border: none; background-color: rgb(218, 218, 218); }
::-webkit-scrollbar-thumb:hover { background-color: rgb(208, 208, 208); }
::-webkit-scrollbar-thumb:active { background-color: rgb(178, 178, 178); }
::-webkit-scrollbar-button:horizontal:increment { background-image: url('data:image/svg+xml;utf8,<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <g>    <g transform="rotate(-90 256.00000000000006,256) " id="svg_1">   <polygon fill="%23333333" id="svg_2" points="128,192 256,320 384,192  "/>  </g> </g></svg>'); background-repeat: no-repeat; background-size: contain; }
::-webkit-scrollbar-button:horizontal:decrement { background-image: url('data:image/svg+xml;utf8,<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <g>    <g transform="rotate(90 255.99999999999997,256.00000000000006) " id="svg_1">   <polygon points="128,192 256,320 384,192  " id="svg_2" fill="%23333333"/>  </g> </g></svg>'); background-repeat: no-repeat; background-size: contain; }
::-webkit-scrollbar-button:vertical:increment { background-image: url('data:image/svg+xml;utf8,<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <g>    <g transform="null" id="svg_1">   <polygon points="128,192 256,320 384,192  " id="svg_2" fill="%23333333"/>  </g> </g></svg>'); background-repeat: no-repeat; background-size: contain; }
::-webkit-scrollbar-button:vertical:decrement { background-image: url('data:image/svg+xml;utf8,<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <g>    <g transform="rotate(180 255.99999999999997,256) " id="svg_1">   <polygon points="128,192 256,320 384,192  " id="svg_2" fill="%23333333"/>  </g> </g></svg>'); background-repeat: no-repeat; background-size: contain; }
::selection { background: rgb(25, 118, 210); color: rgb(238, 238, 238); }
.modal-box { background-color: rgba(234, 234, 234, 0.952941); }
span.modal-close { color: rgb(102, 102, 102); }
span.modal-close:hover, span.modal-close:focus { color: rgb(34, 34, 34); }
.hljs { display: block; overflow-x: auto; padding: 0.5em; background: rgb(224, 224, 224); }
.hljs, .hljs-subst { color: rgb(54, 54, 54); }
.hljs-comment { color: rgb(118, 118, 118); }
.hljs-keyword, .hljs-attribute, .hljs-selector-tag, .hljs-meta-keyword, .hljs-doctag, .hljs-name { color: rgb(0, 0, 238); }
.hljs-type, .hljs-string, .hljs-number, .hljs-selector-id, .hljs-selector-class, .hljs-quote, .hljs-template-tag, .hljs-deletion { color: rgb(136, 0, 0); }
.hljs-title, .hljs-section { color: rgb(136, 0, 0); font-weight: bold; }
.hljs-regexp, .hljs-symbol, .hljs-variable, .hljs-template-variable, .hljs-link, .hljs-selector-attr, .hljs-selector-pseudo { color: rgb(188, 96, 96); }
.hljs-literal { color: rgb(175, 0, 215); }
.hljs-built_in, .hljs-bullet, .hljs-code, .hljs-addition { color: rgb(0, 135, 0); }
.hljs-meta { color: rgb(31, 113, 153); }
.hljs-meta-string { color: rgb(77, 153, 191); }
.hljs-emphasis { font-style: italic; }
.hljs-strong { font-weight: bold; }
.mermaid-diagram .mermaid .label { color: rgb(51, 51, 51); }
.mermaid-diagram .node rect, .mermaid-diagram .node circle, .mermaid-diagram .node ellipse, .mermaid-diagram .node polygon { fill: rgb(236, 236, 255); stroke: rgb(204, 204, 255); stroke-width: 1px; }
.mermaid-diagram .edgePath .path { stroke: rgb(51, 51, 51); }
.mermaid-diagram .edgeLabel { background-color: rgb(232, 232, 232); }
.mermaid-diagram .cluster rect { fill: rgb(255, 255, 222) !important; rx: 4 !important; stroke: rgb(170, 170, 51) !important; stroke-width: 1px !important; }
.mermaid-diagram .cluster text { fill: rgb(51, 51, 51); }
.mermaid-diagram .actor { stroke: rgb(204, 204, 255); fill: rgb(236, 236, 255); }
.mermaid-diagram text.actor { fill: black; stroke: none; }
.mermaid-diagram .actor-line { stroke: grey; }
.mermaid-diagram .messageLine0 { stroke-width: 1.5; stroke: rgb(51, 51, 51); }
.mermaid-diagram .messageLine1 { stroke-width: 1.5; stroke: rgb(51, 51, 51); }
.mermaid-diagram #arrowhead { fill: rgb(51, 51, 51); }
.mermaid-diagram #crosshead path { fill: rgb(51, 51, 51) !important; stroke: rgb(51, 51, 51) !important; }
.mermaid-diagram .messageText { fill: rgb(51, 51, 51); stroke: none; }
.mermaid-diagram .labelBox { stroke: rgb(204, 204, 255); fill: rgb(236, 236, 255); }
.mermaid-diagram .labelText { fill: black; stroke: none; }
.mermaid-diagram .loopText { fill: black; stroke: none; }
.mermaid-diagram .loopLine { stroke-width: 2; stroke: rgb(204, 204, 255); }
.mermaid-diagram .note { stroke: rgb(170, 170, 51); fill: rgb(255, 245, 173); }
.mermaid-diagram .noteText { fill: black; stroke: none; font-family: "trebuchet ms", verdana, arial; font-size: 14px; }
.mermaid-diagram .section { stroke: none; opacity: 0.2; }
.mermaid-diagram .section0 { fill: rgba(102, 102, 255, 0.490196); }
.mermaid-diagram .section2 { fill: rgb(255, 244, 0); }
.mermaid-diagram .section1, .mermaid-diagram .section3 { fill: white; opacity: 0.2; }
.mermaid-diagram .sectionTitle0 { fill: rgb(51, 51, 51); }
.mermaid-diagram .sectionTitle1 { fill: rgb(51, 51, 51); }
.mermaid-diagram .sectionTitle2 { fill: rgb(51, 51, 51); }
.mermaid-diagram .sectionTitle3 { fill: rgb(51, 51, 51); }
.mermaid-diagram .sectionTitle { text-anchor: start; font-size: 11px; }
.mermaid-diagram .grid .tick { stroke: lightgrey; opacity: 0.3; shape-rendering: crispEdges; }
.mermaid-diagram .grid path { stroke-width: 0; }
.mermaid-diagram .today { fill: none; stroke: red; stroke-width: 2px; }
.mermaid-diagram .task { stroke-width: 2; }
.mermaid-diagram .taskText { text-anchor: middle; font-size: 11px; }
.mermaid-diagram .taskTextOutsideRight { fill: black; text-anchor: start; font-size: 11px; }
.mermaid-diagram .taskTextOutsideLeft { fill: black; text-anchor: end; font-size: 11px; }
.mermaid-diagram .taskText0, .mermaid-diagram .taskText1, .mermaid-diagram .taskText2, .mermaid-diagram .taskText3 { fill: white; }
.mermaid-diagram .task0, .mermaid-diagram .task1, .mermaid-diagram .task2, .mermaid-diagram .task3 { fill: rgb(138, 144, 221); stroke: rgb(83, 79, 188); }
.mermaid-diagram .taskTextOutside0, .mermaid-diagram .taskTextOutside2 { fill: black; }
.mermaid-diagram .taskTextOutside1, .mermaid-diagram .taskTextOutside3 { fill: black; }
.mermaid-diagram .active0, .mermaid-diagram .active1, .mermaid-diagram .active2, .mermaid-diagram .active3 { fill: rgb(191, 199, 255); stroke: rgb(83, 79, 188); }
.mermaid-diagram .activeText0, .mermaid-diagram .activeText1, .mermaid-diagram .activeText2, .mermaid-diagram .activeText3 { fill: black !important; }
.mermaid-diagram .done0, .mermaid-diagram .done1, .mermaid-diagram .done2, .mermaid-diagram .done3 { stroke: grey; fill: lightgrey; stroke-width: 2; }
.mermaid-diagram .doneText0, .mermaid-diagram .doneText1, .mermaid-diagram .doneText2, .mermaid-diagram .doneText3 { fill: black !important; }
.mermaid-diagram .crit0, .mermaid-diagram .crit1, .mermaid-diagram .crit2, .mermaid-diagram .crit3 { stroke: rgb(255, 136, 136); fill: red; stroke-width: 2; }
.mermaid-diagram .activeCrit0, .mermaid-diagram .activeCrit1, .mermaid-diagram .activeCrit2, .mermaid-diagram .activeCrit3 { stroke: rgb(255, 136, 136); fill: rgb(191, 199, 255); stroke-width: 2; }
.mermaid-diagram .doneCrit0, .mermaid-diagram .doneCrit1, .mermaid-diagram .doneCrit2, .mermaid-diagram .doneCrit3 { stroke: rgb(255, 136, 136); fill: lightgrey; stroke-width: 2; cursor: pointer; shape-rendering: crispEdges; }
.mermaid-diagram .doneCritText0, .mermaid-diagram .doneCritText1, .mermaid-diagram .doneCritText2, .mermaid-diagram .doneCritText3 { fill: black !important; }
.mermaid-diagram .activeCritText0, .mermaid-diagram .activeCritText1, .mermaid-diagram .activeCritText2, .mermaid-diagram .activeCritText3 { fill: black !important; }
.mermaid-diagram .titleText { text-anchor: middle; font-size: 18px; fill: black; }
.mermaid-diagram .node text { font-family: "trebuchet ms", verdana, arial; font-size: 14px; }
.mermaid-diagram div.mermaidTooltip { position: absolute; text-align: center; max-width: 200px; padding: 2px; font-family: "trebuchet ms", verdana, arial; font-size: 12px; background: rgb(255, 255, 222); border: 1px solid rgb(170, 170, 51); border-radius: 2px; pointer-events: none; z-index: 100; }
#mermaid-diagram-1 .node > rect { }
#mermaid-diagram-1 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-1 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-1 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-1 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-2 .node > rect { }
#mermaid-diagram-2 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-2 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-2 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-2 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-3 .node > rect { }
#mermaid-diagram-3 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-3 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-3 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-3 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-4 .node > rect { }
#mermaid-diagram-4 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-4 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-4 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-4 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-5 .node > rect { }
#mermaid-diagram-5 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-5 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-5 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-5 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-6 .node > rect { }
#mermaid-diagram-6 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-6 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-6 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-6 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-7 .node > rect { }
#mermaid-diagram-7 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-7 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-7 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-7 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-8 .node > rect { }
#mermaid-diagram-8 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-8 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-8 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-8 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-9 .node > rect { }
#mermaid-diagram-9 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-9 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-9 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-9 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-10 .node > rect { }
#mermaid-diagram-10 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-10 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-10 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-10 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-11 .node > rect { }
#mermaid-diagram-11 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-11 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-11 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-11 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-12 .node > rect { }
#mermaid-diagram-12 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-12 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-12 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-12 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-13 .node > rect { }
#mermaid-diagram-13 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-13 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-13 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-13 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-14 .node > rect { }
#mermaid-diagram-14 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-14 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-14 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-14 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-15 .node > rect { }
#mermaid-diagram-15 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-15 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-15 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-15 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-16 .node > rect { }
#mermaid-diagram-16 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-16 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-16 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-16 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-17 .node > rect { }
#mermaid-diagram-17 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-17 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-17 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-17 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-18 .node > rect { }
#mermaid-diagram-18 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-18 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-18 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-18 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-19 .node > rect { }
#mermaid-diagram-19 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-19 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-19 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-19 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-20 .node > rect { }
#mermaid-diagram-20 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-20 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-20 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-20 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-21 .node > rect { }
#mermaid-diagram-21 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-21 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-21 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-21 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }
#mermaid-diagram-22 .node > rect { }
#mermaid-diagram-22 .node text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-22 .edgeLabel text { fill: rgb(0, 0, 0); stroke: none; font-weight: 300; font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; font-size: 14px; }
#mermaid-diagram-22 .cluster rect { fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-22 .cyan > rect, .cyan > polygon, .cyan > circle, .cyan > ellipse { fill: rgb(153, 255, 255); stroke: rgb(255, 255, 255); }

    </style>

    <script type="text/javascript">
var toc = [];

var setVisible = function(node, visible) {
    var cl = 'hide-none';
    if (visible) {
        node.classList.remove(cl);
    } else {
        node.classList.add(cl);
    }
};

var isVisible = function(node) {
    var cl = 'hide-none';
    return !node.classList.contains(cl);
};

var setPostContentExpanded = function(node, expanded) {
    var cl = 'col-expand';
    if (expanded) {
        node.classList.add(cl);
    } else {
        node.classList.remove(cl);
    }
};

var setOutlinePanelVisible = function(visible) {
    var outlinePanel = document.getElementById('outline-panel');
    var postContent = document.getElementById('post-content');

    setVisible(outlinePanel, visible);
    setPostContentExpanded(postContent, !visible);
};

var isOutlinePanelVisible = function() {
    var outlinePanel = document.getElementById('outline-panel');
    return isVisible(outlinePanel);
};

window.addEventListener('load', function() {
    var outlinePanel = document.getElementById('outline-panel');
    outlinePanel.style.display = 'initial';

    var floatingContainer = document.getElementById('container-floating');
    floatingContainer.style.display = 'initial';

    var outlineContent = document.getElementById('outline-content');
    var postContent = document.getElementById('post-content');

    // Escape @text to Html.
    var escapeHtml = function(text) {
        var map = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#039;'
        };

        return text.replace(/[&<>"']/g, function(m) { return map[m]; });
    }

    // Fetch the outline.
    var headers = postContent.querySelectorAll("h1, h2, h3, h4, h5, h6");
    toc = [];
    for (var i = 0; i < headers.length; ++i) {
        var header = headers[i];

        toc.push({
            level: parseInt(header.tagName.substr(1)),
            anchor: header.id,
            title: escapeHtml(header.textContent)
        });
    }

    if (toc.length == 0) {
        setOutlinePanelVisible(false);
        setVisible(floatingContainer, false);
        return;
    }

    var baseLevel = baseLevelOfToc(toc);
    var tocTree = tocToTree(toPerfectToc(toc, baseLevel), baseLevel);

    outlineContent.innerHTML = tocTree;
    setOutlinePanelVisible(true);
    setVisible(floatingContainer, true);
});

// Return the topest level of @toc, starting from 1.
var baseLevelOfToc = function(p_toc) {
    var level = -1;
    for (i in p_toc) {
        if (level == -1) {
            level = p_toc[i].level;
        } else if (level > p_toc[i].level) {
            level = p_toc[i].level;
        }
    }

    if (level == -1) {
        level = 1;
    }

    return level;
};

// Handle wrong title levels, such as '#' followed by '###'
var toPerfectToc = function(p_toc, p_baseLevel) {
    var i;
    var curLevel = p_baseLevel - 1;
    var perfToc = [];
    for (i in p_toc) {
        var item = p_toc[i];

        // Insert empty header.
        while (item.level > curLevel + 1) {
            curLevel += 1;
            var tmp = { level: curLevel,
                        anchor: '',
                        title: '[EMPTY]'
                      };
            perfToc.push(tmp);
        }

        perfToc.push(item);
        curLevel = item.level;
    }

    return perfToc;
};

var itemToHtml = function(item) {
    return '<a href="#' + item.anchor + '" data="' + item.anchor + '">' + item.title + '</a>';
};

// Turn a perfect toc to a tree using <ul>
var tocToTree = function(p_toc, p_baseLevel) {
    var i;
    var front = '<li>';
    var ending = ['</li>'];
    var curLevel = p_baseLevel;
    for (i in p_toc) {
        var item = p_toc[i];
        if (item.level == curLevel) {
            front += '</li>';
            front += '<li>';
            front += itemToHtml(item);
        } else if (item.level > curLevel) {
            // assert(item.level - curLevel == 1)
            front += '<ul>';
            ending.push('</ul>');
            front += '<li>';
            front += itemToHtml(item);
            ending.push('</li>');
            curLevel = item.level;
        } else {
            while (item.level < curLevel) {
                var ele = ending.pop();
                front += ele;
                if (ele == '</ul>') {
                    curLevel--;
                }
            }
            front += '</li>';
            front += '<li>';
            front += itemToHtml(item);
        }
    }
    while (ending.length > 0) {
        front += ending.pop();
    }
    front = front.replace("<li></li>", "");
    front = '<ul>' + front + '</ul>';
    return front;
};

var toggleMore = function() {
    if (toc.length == 0) {
        return;
    }

    var p = document.getElementById('floating-more');
    if (isOutlinePanelVisible()) {
        p.textContent = '<';
        setOutlinePanelVisible(false);
    } else {
        p.textContent = '>';
        setOutlinePanelVisible(true);
    }
};

window.addEventListener('scroll', function() {
    if (toc.length == 0 || !isOutlinePanelVisible()) {
        return;
    }

    var postContent = document.getElementById('post-content');
    var scrollTop = document.documentElement.scrollTop
                    || document.body.scrollTop
                    || window.pageYOffset;
    var eles = postContent.querySelectorAll("h1, h2, h3, h4, h5, h6");

    if (eles.length == 0) {
        return;
    }

    var idx = -1;
    var biaScrollTop = scrollTop + 50;
    for (var i = 0; i < eles.length; ++i) {
        if (biaScrollTop >= eles[i].offsetTop) {
            idx = i;
        } else {
            break;
        }
    }

    var header = '';
    if (idx != -1) {
        header = eles[idx].id;
    }

    highlightItemOnlyInOutline(header);
});

var highlightItemOnlyInOutline = function(id) {
    var cl = 'outline-bold';
    var outlineContent = document.getElementById('outline-content');
    var eles = outlineContent.querySelectorAll("a");
    var target = null;
    for (var i = 0; i < eles.length; ++i) {
        var ele = eles[i];
        if (ele.getAttribute('data') == id) {
            target = ele;
            ele.classList.add(cl);
        } else {
            ele.classList.remove(cl);
        }
    }

    // TODO: scroll target into view within the outline panel scroll area.
};

</script>


<!-- HEAD_PLACE_HOLDER -->
</head>
<body>
<div class="container-fluid">
<div class="row flex-xl-nowrap">
    <div id="outline-panel" style="display:none;" class="d-none d-md-block d-xl-block col-md-3 col-xl-2 bd-toc">
        <div id="outline-content" class="section-nav"></div>
    </div>
    <div id="post-content" class="col-12 col-md-9 col-xl-10 py-md-3 pl-md-5 bd-content">
    <div style="page-break-after: always;"></div>
<h1 id="toc_0">8. 访问外部SQL数据库<a class="vnote-anchor" href="#toc_0" data-anchor-icon="#"></a></h1>
<p><img src='' alt="" class="view-image"></p>
<p>  我们的ORM RESTful框架能够通过一组通用单元和类访问许多数据库引擎。可以访问SQL和NoSQL引擎，这在ORM环境中是一个非常独特的特性。</p>
<p>  请记住介绍mORMot时的这张<a href="">数据库层</a>的图：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-1" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 690.75 654" style="max-width:690.75px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-1 .node&gt;rect { ; }
#mermaid-diagram-1 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-1 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-1 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-1 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph1" transform="translate(284,555)" style="opacity: 1;"><rect width="489" height="118" x="-244.5" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-1Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph0" transform="translate(335.375,339)" style="opacity: 1;"><rect width="630.75" height="118" x="-315.375" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-1Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M278,66.65199161425576L82,125L82,184L82,243L82,280L91.32203389830508,305" marker-end="url(#arrowhead74)" style="fill:none"></path><defs><marker id="arrowhead74" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M278,75.7870036101083L182,125L182,162" marker-end="url(#arrowhead75)" style="fill:none"></path><defs><marker id="arrowhead75" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M170.0677966101695,206L150,243L150,280L130.5084745762712,305" marker-end="url(#arrowhead76)" style="fill:none"></path><defs><marker id="arrowhead76" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M193.9322033898305,206L214,243L214,280L240.80084745762713,305" marker-end="url(#arrowhead77)" style="fill:none"></path><defs><marker id="arrowhead77" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M320.5,88L320.5,125L320.5,184L320.5,243L320.5,280L302.1737288135593,305" marker-end="url(#arrowhead78)" style="fill:none"></path><defs><marker id="arrowhead78" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M363,83.22518159806296L423.75,125L423.75,184L423.75,243L423.75,280L423.75,305" marker-end="url(#arrowhead79)" style="fill:none"></path><defs><marker id="arrowhead79" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M363,66.20424671385237L567.75,125L567.75,184L567.75,243L567.75,280L567.75,305" marker-end="url(#arrowhead80)" style="fill:none"></path><defs><marker id="arrowhead80" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M226.75,364.41151385927503L160,398L160,447L160,496L160,521" marker-end="url(#arrowhead81)" style="fill:none"></path><defs><marker id="arrowhead81" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M327.75,364.41151385927503L394.5,398L394.5,447L394.5,496L394.5,521" marker-end="url(#arrowhead82)" style="fill:none"></path><defs><marker id="arrowhead82" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="translate(82,184)" style="opacity: 1;"><g transform="translate(-20,-12)" class="label"><foreignObject width="40" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">direct</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(182,125)" style="opacity: 1;"><g transform="translate(-20,-12)" class="label"><foreignObject width="40" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">direct</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(150,243)" style="opacity: 1;"><g transform="translate(-22,-12)" class="label"><foreignObject width="44" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">virtual</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(214,243)" style="opacity: 1;"><g transform="translate(-22,-12)" class="label"><foreignObject width="44" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">virtual</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(320.5,184)" style="opacity: 1;"><g transform="translate(-20,-12)" class="label"><foreignObject width="40" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">direct</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(423.75,184)" style="opacity: 1;"><g transform="translate(-20,-12)" class="label"><foreignObject width="40" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">direct</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(567.75,184)" style="opacity: 1;"><g transform="translate(-20,-12)" class="label"><foreignObject width="40" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">direct</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(160,447)" style="opacity: 1;"><g transform="translate(-20,-12)" class="label"><foreignObject width="40" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">direct</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(394.5,447)" style="opacity: 1;"><g transform="translate(-32,-24)" class="label"><foreignObject width="64" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">DB.pas<br>TDataSet</span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="D1" transform="translate(160,555)" style="opacity: 1;"><rect rx="0" ry="0" x="-85.5" y="-34" width="171" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-75.5,-24)"><foreignObject width="151" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle SQLite3 ODBC<br>OleDB ZDBC</div></foreignObject></g></g></g><g class="node cyan" id="D2" transform="translate(394.5,555)" style="opacity: 1;"><rect rx="0" ry="0" x="-99" y="-34" width="198" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-89,-24)"><foreignObject width="178" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">FireDAC AnyDAC UniDAC<br>BDE DBExpress NexusDB</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(104,339)" style="opacity: 1;"><rect rx="0" ry="0" x="-49" y="-34" width="98" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-39,-24)"><foreignObject width="78" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TObjectList<br>NoSQL</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(277.25,339)" style="opacity: 1;"><rect rx="0" ry="0" x="-50.5" y="-34" width="101" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-40.5,-24)"><foreignObject width="81" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">External<br>SQLRDBMS</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(423.75,339)" style="opacity: 1;"><rect rx="0" ry="0" x="-46" y="-34" width="92" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36,-24)"><foreignObject width="72" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MongoDB<br>NoSQL</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(567.75,339)" style="opacity: 1;"><rect rx="0" ry="0" x="-48" y="-34" width="96" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-38,-24)"><foreignObject width="76" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRest<br>redirection</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(320.5,54)" style="opacity: 1;"><rect rx="0" ry="0" x="-42.5" y="-34" width="85" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32.5,-24)"><foreignObject width="65" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">mORMot<br>ORM</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(182,184)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQLite3</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  框架将SQLite3作为其在服务器上的SQL核心，但是特有的机制允许访问任何远程数据库，并将这些表内容与框架的本地ORM表混合。由于SQLite3独特神奇的虚拟表机制，这些外部表可以在SQL语句中视为本地SQLite3表访问，甚至对于NoSQL引擎也是如此。</p>
<table>
<thead>
<tr>
<th>模式</th>
<th>引擎</th>
</tr>
</thead>
<tbody>
<tr>
<td>SQL</td>
<td>SQLite3, Oracle, NexusDB, MS SQL, Jet/MSAccess, FireBird, MySQL, PostgreSQL, IBM DB2, IBM Informix</td>
</tr>
<tr>
<td>NoSQL</td>
<td>MongoDB, JSON或二进制持久性<code>TObjectList</code><br>参见<a href="">访问外部NoSQL数据库</a>和<a href="">内存静态过程</a></td>
</tr>
</tbody>
</table>
<p>  您可以混合使用数据库，如同样的mORMot ORM支持同时对分布在多个数据库的数据持久化，一些<code>TSQLRecord</code>作为快速内部SQLite3表或<code>TObjectList</code>，其它的在PostgreSQL数据库（与外部报告/ SAP引擎绑定），并整合MongoDB实例数据。</p>
<h2 id="toc_1">8.1. SynDB直接RDBMS访问<a class="vnote-anchor" href="#toc_1" data-anchor-icon="#"></a></h2>
<p>  可以通过<code>SynDB.pas</code>单元访问外部关系数据库管理系统（RDBMS）。之后，框架ORM能够通过<code>mORMotDB.pas</code> 单元访问它们。您也可以直接使用<code>SynDB.pas</code>单元，而与我们的ORM没有任何链接。</p>
<p>  当前处理数据访问的库列表如下：</p>
<table>
<thead>
<tr>
<th>驱动</th>
<th>SynDB单元</th>
<th><strong>RDBMS</strong>引擎</th>
</tr>
</thead>
<tbody>
<tr>
<td><em>SQLite3</em></td>
<td><code>SynDBSQLite3.pas</code></td>
<td>直接SQLite3访问(dll或链接到exe)</td>
</tr>
<tr>
<td><em>Oracle</em></td>
<td><code>SynDBOracle.pas</code></td>
<td>直接Oracle访问(通过OCI)</td>
</tr>
<tr>
<td><em>OleDB</em></td>
<td><code>SynOleDB.pas</code></td>
<td>MS SQL, Jet/MSAccess或其他</td>
</tr>
<tr>
<td><em>ODBC</em></td>
<td><code>SynDBODBC.pas</code></td>
<td>MS SQL、FireBird、MySQL、PostgreSQL、IBM DB2、Informix或其他</td>
</tr>
<tr>
<td><em>ZeosLib</em></td>
<td><code>SynDBZeos.pas</code></td>
<td><em>MS SQL, SQLite3, FireBird, MySQL, PostgreSQL</em></td>
</tr>
<tr>
<td><code>DB.pas</code>/<br><code>TDataset</code></td>
<td><code>SynDBDataset.pas</code></td>
<td>NexusDB and databases supported by DBExpress, FireDAC, AnyDac, UniDAC, BDE...</td>
</tr>
<tr>
<td>HTTP</td>
<td><code>SynDBRemote.pas</code></td>
<td>通过HTTP远程访问任何SynDB数据库</td>
</tr>
</tbody>
</table>
<p>  这个列表还没完，可能在不久的将来继续完善。欢迎任何形式的帮助，因为按照现有模式实现一个新单元并不困难，您可以从现有的驱动程序（例如Zeos或Alcinoe库）开始，开源贡献总是受欢迎的！</p>
<p>  感谢我们的<code>SynDB.pas</code>类设计，实现SQLite3直接访问非常简单方便。它甚至被用于我们的回归测试，以实现独立的统一测试。</p>
<p>  添加了针对Oracle的专用的直接访问，因为Oracle所有可用的OleDB驱动程序（微软的和Oracle的）在处理BLOB方面都有问题，我们希望我们的客户端能轻量快速访问这个伟大的数据库。</p>
<p>  事实上，OleDB是一个很好的数据库访问选择，它具有良好的性能、本地Unicode以及许多可用的驱动程序。由于OleDB，我们能够访问几乎任何现有的数据库。与添加其他第三方Delphi库相比，服务端可执行文件中的代码开销也要小得多。我们将使用Microsoft或其它OleDB对每个驱动程序执行所有的测试和调试。</p>
<p>  自版本1.17以来，对ODBC层的直接访问已经包含在框架数据库单元中。它有更广泛的免费驱动（包括MySQL或FireBird），是OleDB的正式替代产品（下一个版本的MS SQL Server将只提供ODBC驱动，就像微软警告其客户的那样）。</p>
<p>  自1.18版以来，可以使用任何ZeosLib/ZDBC驱动快速直接访问RDBMS底层客户端库。因为ZDBC库不依赖于<code>DB.pas</code>，绕过了低效的<code>TDataSet</code> 组件，其性能非常高。ZDBC维护者做了很多优化，特别是与mORMot一起工作，这个库是与我们的框架一起工作的一流库。</p>
<p>  同样自1.18版本，<code>DB.pas</code>可以与我们的<code>SynDB.pas</code>一起使用。当然，使用<code>TDataset</code> 作为中间层会比<code>SynDB.pas</code>直接访问模式慢。但是它允许您复用任何现有（第三方）数据库连接驱动程序，这对存量应用程序的演化是有意义的，或者用于尚未支持的数据库引擎。</p>
<p>  最后但最重要的是，<code>SynDBRemote.pas</code>单元允许您创建在远程<code>SynDB</code> HTTP服务器上执行SQL操作的数据库应用，而不是在数据库服务器上。您可以像其他SynDB数据库一样创建连接，但是传输将通过HTTP进行，不需要在应用程序中安装数据库客户端，参见<a href="">通过HTTP远程访问</a>。</p>
<p>  因此，下列连接是可行的：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-2" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 2202 584" style="max-width:2202px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-2 .node&gt;rect { ; }
#mermaid-diagram-2 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-2 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-2 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-2 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph3" transform="translate(1251,497)" style="opacity: 1;"><rect width="1822" height="94" x="-911" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-2Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph2" transform="translate(198,173)" style="opacity: 1;"><rect width="356" height="118" x="-178" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-2Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph1" transform="translate(764.5,341)" style="opacity: 1;"><rect width="697" height="118" x="-348.5" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-2Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph0" transform="translate(781,173)" style="opacity: 1;"><rect width="636" height="118" x="-318" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-2Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M302.75,46.79591836734694L588.75,89L588.75,114L588.75,139" marker-end="url(#arrowhead191)" style="fill:none"></path><defs><marker id="arrowhead191" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M302.75,44.01850016518004L1027,89L1027,114L1027,139" marker-end="url(#arrowhead192)" style="fill:none"></path><defs><marker id="arrowhead192" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M302.75,54.14711729622266L396,89L396,114L396,173L396,232L396,257L396,282L396,341L396,400L396,425L396,450L411.95744680851067,475" marker-end="url(#arrowhead193)" style="fill:none"></path><defs><marker id="arrowhead193" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M302.75,43.770501303969866L1133,89L1133,114L1133,173L1133,232L1133,257L1133,282L1133,341L1133,400L535.5,425L535.5,450L540.8191489361702,475" marker-end="url(#arrowhead194)" style="fill:none"></path><defs><marker id="arrowhead194" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M237.75,50.22341857335128L84.5,89L84.5,114L84.5,139" marker-end="url(#arrowhead195)" style="fill:none"></path><defs><marker id="arrowhead195" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M237.75,62.71186440677966L196.5,89L196.5,114L196.5,151" marker-end="url(#arrowhead196)" style="fill:none"></path><defs><marker id="arrowhead196" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M288.8563829787234,64L310,89L310,114L310,151" marker-end="url(#arrowhead197)" style="fill:none"></path><defs><marker id="arrowhead197" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M549.707627118644,207L521,232L521,257L521,282L521,307" marker-end="url(#arrowhead198)" style="fill:none"></path><defs><marker id="arrowhead198" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M627.792372881356,207L656.5,232L656.5,257L656.5,282L656.5,319" marker-end="url(#arrowhead199)" style="fill:none"></path><defs><marker id="arrowhead199" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M629.75,184.9900867410161L790.5,232L790.5,257L790.5,282L790.5,319" marker-end="url(#arrowhead200)" style="fill:none"></path><defs><marker id="arrowhead200" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M629.75,180.72226656025538L902,232L902,257L902,282L902,319" marker-end="url(#arrowhead201)" style="fill:none"></path><defs><marker id="arrowhead201" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1027,207L1027,232L1027,257L1027,282L1027,319" marker-end="url(#arrowhead202)" style="fill:none"></path><defs><marker id="arrowhead202" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M493.33898305084745,375L473,400L473,425L473,450L448,475" marker-end="url(#arrowhead203)" style="fill:none"></path><defs><marker id="arrowhead203" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M560,348.727959697733L818.75,400L818.75,425L818.75,450L578,491.4098810612992" marker-end="url(#arrowhead204)" style="fill:none"></path><defs><marker id="arrowhead204" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="E1" transform="translate(426,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQLite3</div></foreignObject></g></g></g><g class="node cyan" id="E2" transform="translate(545.5,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle</div></foreignObject></g></g></g><g class="node cyan" id="E3" transform="translate(665.5,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MS SQL</div></foreignObject></g></g></g><g class="node cyan" id="E4" transform="translate(787,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-34" y="-22" width="68" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-24,-12)"><foreignObject width="48" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Sybase</div></foreignObject></g></g></g><g class="node cyan" id="E5" transform="translate(921.5,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-50.5" y="-22" width="101" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-40.5,-12)"><foreignObject width="81" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">PostgreSQL</div></foreignObject></g></g></g><g class="node cyan" id="E6" transform="translate(1068.5,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Jet/Access</div></foreignObject></g></g></g><g class="node cyan" id="E7" transform="translate(1202,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Firebird</div></foreignObject></g></g></g><g class="node cyan" id="E8" transform="translate(1324,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-35" y="-22" width="70" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-25,-12)"><foreignObject width="50" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MySQL</div></foreignObject></g></g></g><g class="node cyan" id="E9" transform="translate(1457,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-48" y="-22" width="96" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-38,-12)"><foreignObject width="76" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Advantage</div></foreignObject></g></g></g><g class="node cyan" id="E10" transform="translate(1597.5,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-42.5" y="-22" width="85" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32.5,-12)"><foreignObject width="65" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Interbase</div></foreignObject></g></g></g><g class="node cyan" id="E11" transform="translate(1729,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-39" y="-22" width="78" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-29,-12)"><foreignObject width="58" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Informix</div></foreignObject></g></g></g><g class="node cyan" id="E12" transform="translate(1842.5,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-24.5" y="-22" width="49" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-14.5,-12)"><foreignObject width="29" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB2</div></foreignObject></g></g></g><g class="node cyan" id="E13" transform="translate(1955,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-38" y="-22" width="76" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-28,-12)"><foreignObject width="56" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Paradox</div></foreignObject></g></g></g><g class="node cyan" id="E14" transform="translate(2085,497)" style="opacity: 1;"><rect rx="0" ry="0" x="-42" y="-22" width="84" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32,-12)"><foreignObject width="64" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">NexusDB</div></foreignObject></g></g></g><g class="node cyan" id="D1" transform="translate(84.5,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-29.5" y="-34" width="59" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-19.5,-24)"><foreignObject width="39" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ZDBC<br>Zeos</div></foreignObject></g></g></g><g class="node cyan" id="D2" transform="translate(196.5,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">OleDB</div></foreignObject></g></g></g><g class="node cyan" id="D3" transform="translate(310,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-31" y="-22" width="62" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-21,-12)"><foreignObject width="42" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ODBC</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(521,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-39" y="-34" width="78" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-29,-24)"><foreignObject width="58" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">FireDAC<br>AnyDAC</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(656.5,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DBExpress</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(790.5,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">UniDAC</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(902,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-24" y="-22" width="48" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-14,-12)"><foreignObject width="28" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">BDE</div></foreignObject></g></g></g><g class="node cyan" id="C5" transform="translate(1027,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-51" y="-22" width="102" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-41,-12)"><foreignObject width="82" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">any RDBMS</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(588.75,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-41" y="-34" width="82" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-31,-24)"><foreignObject width="62" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB.pas<br>TDataset</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(1027,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-34" width="74" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-24)"><foreignObject width="54" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB<br>Remote</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(270.25,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  这个图在最新的层次上有点难理解，但是我想您已经得到了通用的分层设计，稍后它将被分割成更小的聚焦图。</p>
<h3 id="toc_2">8.1.1. 直接访问RDBMS引擎<a class="vnote-anchor" href="#toc_2" data-anchor-icon="#"></a></h3>
<p>  SynDB.pas单元有如下特点：</p>
<ul>
<li>通过OleDB、ODBC、ZDBC、Oracle (OCI)或SQLite3(静态链接或外部dll)直接快速访问；</li>
<li>对基于<code>DB.pas</code> / <code>TDataset</code>的组件的轻量包装器（如NexusDB、DBExpress、FireDAC、AnyDAC、UniDAC、BDE…）</li>
<li>通用抽象OOP方案，使用一组受限制的数据类型，但能够与任何基于SQL的数据库引擎一起工作；</li>
<li>通过了MS SQL Server 2008/2012、Firebird 2.5.1、PostgreSQL 9.2/9.3、MySQL 5.6、IBM DB2 10.5、Oracle 11g以及最新的SQLite3引擎测试；</li>
<li>可以使用任何Delphi版本（包括Delphi 7 personal、Turbo Explorer或Starter edition）访问任何本地或远程数据库，而且是免费的（事实上，它不使用<code>DB.pas</code>标准单位元及其所有依赖单元）；</li>
<li>Unicode，包括Delphi以前的Unicode版本（如Delphi 7或2007），因为它在内部使用UTF-8编码；</li>
<li>可以处理NULL或BLOB内容的参数和结果（包括存储过程）；</li>
<li>避免了很多的内存复制或不必要的内存分配：我们直接从检索到的数据缓冲区访问数据，就像从OleDB / ODBC或底层数据库客户端（例如Oracle的OCI，或SQLite3引擎）访问数据一样；</li>
<li>为32位或64位Windows设计实现最佳性能：大部分时间花在数据库驱动程序（OleDB、ODBC、OCI、SQLite3）上，添加到数据库客户端的代码层非常轻量，并经过了优化；</li>
<li>可以在多线程应用/服务器中安全使用（使用专用的线程安全方法，即使数据库客户端不是官方正式的多线程也可以使用）；</li>
<li>允许对就绪的请求进行参数绑定，快速访问任何参数或列名（多亏了<code>TDynArrayHashed</code>）；</li>
<li>大多数Delphi类型都可以访问列值，包括变体或泛型字符串/ WideString；</li>
<li>可用的<code>ISQLDBRows</code>接口，避免键入<code>try...finally Query.Free end;</code>并允许单条SQL语句；</li>
<li>后期绑定列访问，通过自定义变体类型访问结果集；</li>
<li>两种优化的<code>TDataSet</code>结果集：一种是基于<code>TClientDataSet</code>的读写，另一种是更快的只读<code>TSynSQLStatementDataSet</code>。</li>
<li>直接创建UTF-8 JSON内容，不需要临时数据复制和内存分配（该特性将是我们基于JSON的ORM服务端中最常用的特性）；</li>
<li>高级目录/数据库设计抽象方法，支持在数据库反向工程中检索表和列属性（包括索引）；还提供SQL语句以数据库抽象的方式创建表或索引，这些特性将被我们的ORM直接使用；</li>
<li>设计用于ORM，但也可以单独使用（完整的Delphi 7客户端可执行文件只有大约200kb），也可以在任何现有的Delphi应用程序中使用，这要归功于一个类似<code>TQuery</code>的包装器；</li>
<li>TQuery仿真类，用于与现有代码直接重用，已替换为基于DB.pas的代码（包括过时的BDE技术），极大地提高了速度（因为我们绕过了极慢的<code>TDataSet</code>组件）；</li>
<li>通过HTTP对任何<code>SynDB</code>引擎进行快速和安全的远程访问，而不需要将RDBMS客户端库与应用程序一起部署；</li>
<li>免费的SynDBExplorer工具，一个简单快速运行查询的用户界面，对所有支持的引擎，发布为服务端或作为<code>SynDB</code>客户端通过HTTP远程访问，它也是独立使用这些库的一个很好的示例程序。</li>
</ul>
<h3 id="toc_3">8.1.2. 数据类型<a class="vnote-anchor" href="#toc_3" data-anchor-icon="#"></a></h3>
<p>  我们的ORM不需要完整的特性集（不要指望将这个数据库类用于您的VCL DB RAD组件），仅处理我们需要的基本的SQL列类型（派生自SQLite的内部列类型）： <code>NULL, Int64, Double, Currency, DateTime, RawUTF8</code> 和<code>BLOB</code>。</p>
<p>  它们在<code>SyncDB .pas</code>中定义如下：</p>
<pre><code class="lang-pascal hljs">  TSQLDBFieldType =
    (ftUnknown, ftNull, ftInt64, ftDouble, ftCurrency, ftDate, ftUTF8, ftBlob);
</code></pre>
<table>
<thead>
<tr>
<th><strong>TSQLDBFieldType</strong></th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ftNull</code></td>
<td>对应SQL的NULL值</td>
</tr>
<tr>
<td><code>ftInt64</code></td>
<td>64位整数</td>
</tr>
<tr>
<td><code>ftDouble</code></td>
<td>64位浮点数</td>
</tr>
<tr>
<td><code>ftCurrency</code></td>
<td>财务类型，最多4位小数（货币）</td>
</tr>
<tr>
<td><code>ftDate</code></td>
<td>日期和时间，对应Delphi的<code>TDateTime</code>类型</td>
</tr>
<tr>
<td><code>ftUTF8</code></td>
<td>Unicode文本，UTF-8编码，有或没有大小限制</td>
</tr>
<tr>
<td><code>ftBlob</code></td>
<td>二进制内容，存储为RawByteString</td>
</tr>
</tbody>
</table>
<p>  这些类型将映射为底层数据库级访问类型，而不是像在<code>mORMot.pas</code>中定义的<code>TSQLFieldType</code>那样的高级Delphi类型，也不是标准VCL<code>DB.pas</code>单元中定义的泛型大型<code>TFieldType</code> 。事实上，它更依赖于标准的SQLite3泛型类型，即NULL、INTEGER、REAL、TEXT、BLOB（添加了<code>ftCurrency</code>和<code>ftDate</code>类型，以更好地支持大多数DB引擎），请参见http://www.sqlite.org/datatype3.html。</p>
<p>  您可能注意到这里唯一处理的字符串类型使用UTF-8编码（使用我们的RawUTF8类型实现），用于跨delphi版本实现真正Unicode处理。代码可以通过<code>variant</code>、<code>string</code>或<code>widestring</code>变量和参数访问文本数据，但是我们的单元将在内部使用UTF-8编码，请参阅<a href="">Unicode和UTF-8</a>，因此，它将与使用同样编码的ORM直接接口。当然，如果某列在数据库中没有定义为Unicode文本，则需要在数据驱动级实现与对应字符集的相互转换；但是在用户相关代码中，您应该始终使用Unicode内容。</p>
<p>  BLOB列或参数作为<code>RawByteString</code>变量访问，这些变量通过<code>TRawByteStringStream</code>映射为标准<code>TStream</code>。</p>
<h3 id="toc_4">8.1.3. 数据库类型<a class="vnote-anchor" href="#toc_4" data-anchor-icon="#"></a></h3>
<p>  除了原始数据访问，<code>SynDB.pas</code>单元还处理一些SQL级语句生成，并用于我们的ORM内核使用。</p>
<p>  以下RDBMS数据库引擎在<code>SynDB.pas</code>中的定义：</p>
<pre><code class="lang-pascal hljs"> TSQLDBDefinition = (dUnknown, dDefault, dOracle, dMSSQL, dJet,
   dMySQL, dSQLite, dFirebird, dNexusDB, dPostgreSQL, dDB2, dInformix);
</code></pre>
<table>
<thead>
<tr>
<th><strong>TSQLDBDefinition</strong></th>
<th><strong>已测试的RDBMS</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>dDefault</code></td>
<td>遵循SQL-92标准的任何数据库</td>
</tr>
<tr>
<td><code>dOracle</code></td>
<td>Oracle 11g</td>
</tr>
<tr>
<td><code>dMSSQL</code></td>
<td>MS SQL Server 2008/2012</td>
</tr>
<tr>
<td><code>dJet</code></td>
<td>Jet/MSAccess （仅支持<em>Win32</em>）</td>
</tr>
<tr>
<td><code>dMySQL</code></td>
<td>MySQL 5.6</td>
</tr>
<tr>
<td><code>dSQLite</code></td>
<td>SQLite3 3.7.11及以上版本（我们为静态链接提供了最新版本）</td>
</tr>
<tr>
<td><code>dFirebird</code></td>
<td>Firebird 2.5.1</td>
</tr>
<tr>
<td><code>dNexusDB</code></td>
<td>NexusDB 3.11</td>
</tr>
<tr>
<td><code>dPostgreSQL</code></td>
<td>PostgreSQL 9.2/9.3</td>
</tr>
<tr>
<td><code>dDB2</code></td>
<td>IBM DB2 10.5</td>
</tr>
<tr>
<td><code>dInformix</code></td>
<td>IBM Informix 11.70</td>
</tr>
</tbody>
</table>
<p>  以上版本已经经过测试，但是更新或更老的版本也可以工作。欢迎您的反馈，我们无法完成对数据库和客户端所有可能组合的测试！</p>
<p>  <code>SynDB.pas</code>单元能够生成上述引擎的SQL语句，<code>CREATE TABLE</code> / <code>CREATE INDEX</code>命令，检索元数据（如表和字段信息），正确计算<code>SELECT</code>的limit/offset语法、计算多条INSERT语句，检查SQL关键字，定义特定的schema/owner命名约定，处理日期和时间值，处理错误和异常，甚至创建一个数据库。</p>
<h3 id="toc_5">8.1.4. SynDB单元<a class="vnote-anchor" href="#toc_5" data-anchor-icon="#"></a></h3>
<p>  以下是实现外部数据库无关特性的单元：</p>
<table>
<thead>
<tr>
<th>文件</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>SynDB.pas</code></td>
<td>抽象的数据库直接访问类</td>
</tr>
<tr>
<td><code>SynOleDB.pas</code></td>
<td>OleDB直接访问类</td>
</tr>
<tr>
<td><code>SynDBODBC.pas</code></td>
<td>ODBC直接访问类</td>
</tr>
<tr>
<td><code>SynDBZeos.pas</code></td>
<td>ZDBC直接访问类</td>
</tr>
<tr>
<td><code>SynDBOracle.pas</code></td>
<td>Oracle DB直接访问类（通过OCI）</td>
</tr>
<tr>
<td><code>SynDBSQLite3.pas</code></td>
<td>SQLite3直接访问类</td>
</tr>
<tr>
<td><code>SynDBDataset.pas</code></td>
<td><code>TDataset</code> (<code>DB.pas</code>)访问类</td>
</tr>
<tr>
<td><code>SynDBFireDAC.pas</code></td>
<td><code>TDataset</code> (<code>DB.pas</code>)访问类</td>
</tr>
<tr>
<td><code>SynDBUniDAC.pas</code></td>
<td><code>TDataset</code> (<code>DB.pas</code>)访问类</td>
</tr>
<tr>
<td><code>SynDBNexusDB.pas</code></td>
<td><code>TDataset</code> (<code>DB.pas</code>)访问类</td>
</tr>
<tr>
<td><code>SynDBBDE.pas</code></td>
<td><code>TDataset</code> (<code>DB.pas</code>)访问类</td>
</tr>
<tr>
<td><code>SynDBRemote.pas</code></td>
<td>HTTP远程访问</td>
</tr>
<tr>
<td><code>SynDBVCL</code></td>
<td>只读的<code>TSynSQLStatementDataSet</code>结果集</td>
</tr>
<tr>
<td><code>SynDBMidasVCL</code></td>
<td>可读写的<code>TClientDataSet</code>结果集</td>
</tr>
</tbody>
</table>
<p>  值得注意的是，这些单元只依赖于<code>SynCommons.pas</code>，它们独立于框架的ORM部分（甚至远程访问）。它们可以单独使用，使用普通SQL代码访问所有这些外部数据库。它们的所有类都继承自<code>SynDB.pas</code>中定义的抽象类，所以从一个数据库引擎切换到另一个数据库引擎（即便是远程HTTP访问）只是更改一个类型的问题。</p>
<h3 id="toc_6">8.1.5. SynDB类<a class="vnote-anchor" href="#toc_6" data-anchor-icon="#"></a></h3>
<p>  数据通过三大类访问：</p>
<ul>
<li>连接属性，存储数据库高级属性（如数据库实现类、服务器和数据库名称、用户名和密码）；</li>
<li>连接，根据指定的连接属性实现到远程数据库的实际连接，对于相同的连接属性实例，可以有多个连接;</li>
<li>语句，这些语句是单个SQL查询或请求，对于一个现有连接可能有很多。</li>
</ul>
<p>  在实践中，您定义一个<code>TSQLDBConnectionProperties</code>实例，然后使用专用的<code>NewConnection</code> / <code>ThreadSafeConnection</code> / <code>NewStatement</code>方法生成<code>TSQLDBConnection</code> and <code>TSQLDBStatement</code>实例。</p>
<p>  以下是所有可用远程连接属性的通用类层次结构：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-3" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1936 1302" style="max-width:1936px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-3 .node&gt;rect { ; }
#mermaid-diagram-3 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-3 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-3 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-3 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph3" transform="translate(200,617.5)" style="opacity: 1;"><rect width="360" height="443" x="-180" y="-221.5"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-207.5" fill="black" stroke="none" id="mermaid-diagram-3Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph2" transform="translate(602.5,688)" style="opacity: 1;"><rect width="345" height="1148" x="-172.5" y="-574"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-560" fill="black" stroke="none" id="mermaid-diagram-3Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph1" transform="translate(1008.5,631.75)" style="opacity: 1;"><rect width="367" height="1223.5" x="-183.5" y="-611.75"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-597.75" fill="black" stroke="none" id="mermaid-diagram-3Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph0" transform="translate(1429.5,616.75)" style="opacity: 1;"><rect width="375" height="1159.5" x="-187.5" y="-579.75"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-565.75" fill="black" stroke="none" id="mermaid-diagram-3Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M346.5,453L380,453L405,453L430,453L467.5,453" marker-end="url(#arrowhead345)" style="fill:none"></path><defs><marker id="arrowhead345" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M355,641L380,641L405,641L430,641L562.1276595744681,713" marker-end="url(#arrowhead346)" style="fill:none"></path><defs><marker id="arrowhead346" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M355,782L380,782L405,782L430,782L521.7553191489362,757" marker-end="url(#arrowhead347)" style="fill:none"></path><defs><marker id="arrowhead347" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M745,171L775,171L800,171L825,171L965.5531914893617,243" marker-end="url(#arrowhead348)" style="fill:none"></path><defs><marker id="arrowhead348" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M744,265L775,265L800,265L825,265L867,265" marker-end="url(#arrowhead349)" style="fill:none"></path><defs><marker id="arrowhead349" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M731.5,359L775,359L800,359L825,359L965.5531914893617,287" marker-end="url(#arrowhead350)" style="fill:none"></path><defs><marker id="arrowhead350" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M737.5,453L775,453L800,453L825,453L991.3212765957447,666" marker-end="url(#arrowhead351)" style="fill:none"></path><defs><marker id="arrowhead351" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M750,547L775,547L800,547L825,547L979.8687943262412,666" marker-end="url(#arrowhead352)" style="fill:none"></path><defs><marker id="arrowhead352" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M740,641L775,641L800,641L825,641L922.6063829787234,666" marker-end="url(#arrowhead353)" style="fill:none"></path><defs><marker id="arrowhead353" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M740,735L775,735L800,735L825,735L922.6063829787234,710" marker-end="url(#arrowhead354)" style="fill:none"></path><defs><marker id="arrowhead354" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M724.5,829L775,829L800,829L825,829L979.8687943262412,710" marker-end="url(#arrowhead355)" style="fill:none"></path><defs><marker id="arrowhead355" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M737.5,923L775,923L800,923L825,923L991.3212765957447,710" marker-end="url(#arrowhead356)" style="fill:none"></path><defs><marker id="arrowhead356" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M731.5,1017L775,1017L800,1017L825,1017L979.8687943262412,1136" marker-end="url(#arrowhead357)" style="fill:none"></path><defs><marker id="arrowhead357" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M749.5,1111L775,1111L800,1111L825,1111L922.6063829787234,1136" marker-end="url(#arrowhead358)" style="fill:none"></path><defs><marker id="arrowhead358" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M746,1205L775,1205L800,1205L825,1205L922.6063829787234,1180" marker-end="url(#arrowhead359)" style="fill:none"></path><defs><marker id="arrowhead359" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1142,77L1192,77L1217,77L1242,77L1419.7482269503546,478" marker-end="url(#arrowhead360)" style="fill:none"></path><defs><marker id="arrowhead360" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1146,171L1192,171L1217,171L1242,171L1416.9620060790273,478" marker-end="url(#arrowhead361)" style="fill:none"></path><defs><marker id="arrowhead361" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1150,265L1192,265L1217,265L1242,265L1411.9468085106382,478" marker-end="url(#arrowhead362)" style="fill:none"></path><defs><marker id="arrowhead362" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1121,688L1192,688L1217,688L1242,688L1407.5585106382978,522" marker-end="url(#arrowhead363)" style="fill:none"></path><defs><marker id="arrowhead363" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1119.5,876L1192,876L1217,876L1242,876L1418.529255319149,522" marker-end="url(#arrowhead364)" style="fill:none"></path><defs><marker id="arrowhead364" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1155,970L1192,970L1217,970L1242,970L1420.723404255319,522" marker-end="url(#arrowhead365)" style="fill:none"></path><defs><marker id="arrowhead365" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1146.5,1064L1192,1064L1217,1064L1242,1064L1341.7340425531916,1089" marker-end="url(#arrowhead366)" style="fill:none"></path><defs><marker id="arrowhead366" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1167,1158L1192,1158L1217,1158L1242,1158L1341.7340425531916,1133" marker-end="url(#arrowhead367)" style="fill:none"></path><defs><marker id="arrowhead367" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1571.5,94L1617,94L1642,94L1773.9408866995075,478" marker-end="url(#arrowhead368)" style="fill:none"></path><defs><marker id="arrowhead368" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1583.5,500L1617,500L1642,500L1667,500" marker-end="url(#arrowhead369)" style="fill:none"></path><defs><marker id="arrowhead369" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1592,1111L1617,1111L1642,1111L1776.477086743044,522" marker-end="url(#arrowhead370)" style="fill:none"></path><defs><marker id="arrowhead370" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A1" transform="translate(200,453)" style="opacity: 1;"><rect rx="0" ry="0" x="-146.5" y="-22" width="293" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-136.5,-12)"><foreignObject width="273" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBMSOracleConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="A2" transform="translate(200,641)" style="opacity: 1;"><rect rx="0" ry="0" x="-155" y="-22" width="310" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-145,-12)"><foreignObject width="290" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBMSSQL2012ConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="A3" transform="translate(200,782)" style="opacity: 1;"><rect rx="0" ry="0" x="-155" y="-22" width="310" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-145,-12)"><foreignObject width="290" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBMSSQL2005ConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(602.5,171)" style="opacity: 1;"><rect rx="0" ry="0" x="-142.5" y="-22" width="285" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-132.5,-12)"><foreignObject width="265" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBFireDACConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(602.5,265)" style="opacity: 1;"><rect rx="0" ry="0" x="-141.5" y="-22" width="283" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-131.5,-12)"><foreignObject width="263" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBUniDACConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B3" transform="translate(602.5,359)" style="opacity: 1;"><rect rx="0" ry="0" x="-129" y="-22" width="258" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-119,-12)"><foreignObject width="238" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBBDEConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B4" transform="translate(602.5,453)" style="opacity: 1;"><rect rx="0" ry="0" x="-135" y="-22" width="270" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-125,-12)"><foreignObject width="250" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBOracleConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B5" transform="translate(602.5,547)" style="opacity: 1;"><rect rx="0" ry="0" x="-147.5" y="-22" width="295" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-137.5,-12)"><foreignObject width="275" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBODBCSQLConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B6" transform="translate(602.5,641)" style="opacity: 1;"><rect rx="0" ry="0" x="-137.5" y="-22" width="275" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-127.5,-12)"><foreignObject width="255" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBMySQLConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B7" transform="translate(602.5,735)" style="opacity: 1;"><rect rx="0" ry="0" x="-137.5" y="-22" width="275" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-127.5,-12)"><foreignObject width="255" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBMSSQLConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B8" transform="translate(602.5,829)" style="opacity: 1;"><rect rx="0" ry="0" x="-122" y="-22" width="244" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-112,-12)"><foreignObject width="224" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBJetConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B9" transform="translate(602.5,923)" style="opacity: 1;"><rect rx="0" ry="0" x="-135" y="-22" width="270" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-125,-12)"><foreignObject width="250" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBAS400ConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B10" transform="translate(602.5,1017)" style="opacity: 1;"><rect rx="0" ry="0" x="-129" y="-22" width="258" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-119,-12)"><foreignObject width="238" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBCurlConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B11" transform="translate(602.5,1111)" style="opacity: 1;"><rect rx="0" ry="0" x="-147" y="-22" width="294" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-137,-12)"><foreignObject width="274" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBWinHTTPConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B12" transform="translate(602.5,1205)" style="opacity: 1;"><rect rx="0" ry="0" x="-143.5" y="-22" width="287" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-133.5,-12)"><foreignObject width="267" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBWinINetConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(1008.5,77)" style="opacity: 1;"><rect rx="0" ry="0" x="-133.5" y="-22" width="267" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-123.5,-12)"><foreignObject width="247" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBZEOSConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(1008.5,171)" style="opacity: 1;"><rect rx="0" ry="0" x="-137.5" y="-22" width="275" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-127.5,-12)"><foreignObject width="255" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBOracleConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(1008.5,265)" style="opacity: 1;"><rect rx="0" ry="0" x="-141.5" y="-22" width="283" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-131.5,-12)"><foreignObject width="263" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBDatasetConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(1008.5,688)" style="opacity: 1;"><rect rx="0" ry="0" x="-112.5" y="-22" width="225" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-102.5,-12)"><foreignObject width="205" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C5" transform="translate(1008.5,876)" style="opacity: 1;"><rect rx="0" ry="0" x="-111" y="-22" width="222" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-101,-12)"><foreignObject width="202" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TODBCConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C6" transform="translate(1008.5,970)" style="opacity: 1;"><rect rx="0" ry="0" x="-146.5" y="-22" width="293" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-136.5,-12)"><foreignObject width="273" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBNexusDBConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C7" transform="translate(1008.5,1064)" style="opacity: 1;"><rect rx="0" ry="0" x="-138" y="-22" width="276" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-128,-12)"><foreignObject width="256" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBSocketConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C8" transform="translate(1008.5,1158)" style="opacity: 1;"><rect rx="0" ry="0" x="-158.5" y="-22" width="317" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-148.5,-12)"><foreignObject width="297" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBHttpRequestConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="D1" transform="translate(1429.5,94)" style="opacity: 1;"><rect rx="0" ry="0" x="-142" y="-22" width="284" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-132,-12)"><foreignObject width="264" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBSQLite3ConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="D2" transform="translate(1429.5,500)" style="opacity: 1;"><rect rx="0" ry="0" x="-154" y="-22" width="308" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-144,-12)"><foreignObject width="288" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBConnectionPropertiesThreadSafe</div></foreignObject></g></g></g><g class="node cyan" id="D3" transform="translate(1429.5,1111)" style="opacity: 1;"><rect rx="0" ry="0" x="-162.5" y="-22" width="325" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-152.5,-12)"><foreignObject width="305" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBHTTPConnectionPropertiesAbstract</div></foreignObject></g></g></g><g class="node cyan" id="E" transform="translate(1781.5,500)" style="opacity: 1;"><rect rx="0" ry="0" x="-114.5" y="-22" width="229" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-104.5,-12)"><foreignObject width="209" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBConnectionProperties</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  这些类是<code>SynDB.pas</code>的根类，大部分数据库处理将通过该单元实现。mORMot框架的ORM只需要给定的<code>TSQLDBConnectionProperties</code>实例就可以访问任何外部数据库。</p>
<p>  然后定义了以下连接类：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-4" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 874 832" style="max-width:874px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-4 .node&gt;rect { ; }
#mermaid-diagram-4 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-4 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-4 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-4 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph1" transform="translate(155.5,406)" style="opacity: 1;"><rect width="271" height="772" x="-135.5" y="-386"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-372" fill="black" stroke="none" id="mermaid-diagram-4Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph0" transform="translate(484,405.25)" style="opacity: 1;"><rect width="286" height="736.5" x="-143" y="-368.25"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-354.25" fill="black" stroke="none" id="mermaid-diagram-4Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M590,94L627,94L652,94L738.3150943396226,204.5" marker-end="url(#arrowhead434)" style="fill:none"></path><defs><marker id="arrowhead434" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M582,188L627,188L652,188L696.3571428571429,204.5" marker-end="url(#arrowhead435)" style="fill:none"></path><defs><marker id="arrowhead435" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M602,406L627,406L652,406L742.8147632311977,248.5" marker-end="url(#arrowhead436)" style="fill:none"></path><defs><marker id="arrowhead436" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M230.5,77L291,77L316,77L341,77L474.4376899696049,384" marker-end="url(#arrowhead437)" style="fill:none"></path><defs><marker id="arrowhead437" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M232,171L291,171L316,171L341,171L470.6127659574468,384" marker-end="url(#arrowhead438)" style="fill:none"></path><defs><marker id="arrowhead438" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M248.5,265L291,265L316,265L341,265L461.68794326241135,384" marker-end="url(#arrowhead439)" style="fill:none"></path><defs><marker id="arrowhead439" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M257,359L291,359L316,359L341,359L417.06382978723406,384" marker-end="url(#arrowhead440)" style="fill:none"></path><defs><marker id="arrowhead440" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M262,453L291,453L316,453L341,453L417.06382978723406,428" marker-end="url(#arrowhead441)" style="fill:none"></path><defs><marker id="arrowhead441" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M261.5,547L291,547L316,547L341,547L461.68794326241135,428" marker-end="url(#arrowhead442)" style="fill:none"></path><defs><marker id="arrowhead442" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M253,641L291,641L316,641L341,641L470.6127659574468,428" marker-end="url(#arrowhead443)" style="fill:none"></path><defs><marker id="arrowhead443" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M266,735L291,735L316,735L341,735L474.4376899696049,428" marker-end="url(#arrowhead444)" style="fill:none"></path><defs><marker id="arrowhead444" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A1" transform="translate(155.5,77)" style="opacity: 1;"><rect rx="0" ry="0" x="-75" y="-22" width="150" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-65,-12)"><foreignObject width="130" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TODBCConnection</div></foreignObject></g></g></g><g class="node cyan" id="A2" transform="translate(155.5,171)" style="opacity: 1;"><rect rx="0" ry="0" x="-76.5" y="-22" width="153" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-66.5,-12)"><foreignObject width="133" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBConnection</div></foreignObject></g></g></g><g class="node cyan" id="A3" transform="translate(155.5,265)" style="opacity: 1;"><rect rx="0" ry="0" x="-93" y="-22" width="186" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-83,-12)"><foreignObject width="166" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBBDEConnection</div></foreignObject></g></g></g><g class="node cyan" id="A4" transform="translate(155.5,359)" style="opacity: 1;"><rect rx="0" ry="0" x="-101.5" y="-22" width="203" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-91.5,-12)"><foreignObject width="183" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBOracleConnection</div></foreignObject></g></g></g><g class="node cyan" id="A5" transform="translate(155.5,453)" style="opacity: 1;"><rect rx="0" ry="0" x="-106.5" y="-22" width="213" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-96.5,-12)"><foreignObject width="193" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBFireDACConnection</div></foreignObject></g></g></g><g class="node cyan" id="A6" transform="translate(155.5,547)" style="opacity: 1;"><rect rx="0" ry="0" x="-106" y="-22" width="212" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-96,-12)"><foreignObject width="192" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBUniDACConnection</div></foreignObject></g></g></g><g class="node cyan" id="A7" transform="translate(155.5,641)" style="opacity: 1;"><rect rx="0" ry="0" x="-97.5" y="-22" width="195" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-87.5,-12)"><foreignObject width="175" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBZEOSConnection</div></foreignObject></g></g></g><g class="node cyan" id="A8" transform="translate(155.5,735)" style="opacity: 1;"><rect rx="0" ry="0" x="-110.5" y="-22" width="221" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-100.5,-12)"><foreignObject width="201" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBNexusDBConnection</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(484,94)" style="opacity: 1;"><rect rx="0" ry="0" x="-106" y="-22" width="212" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-96,-12)"><foreignObject width="192" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBSQLite3Connection</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(484,188)" style="opacity: 1;"><rect rx="0" ry="0" x="-98" y="-22" width="196" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-88,-12)"><foreignObject width="176" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBProxyConnection</div></foreignObject></g></g></g><g class="node cyan" id="B3" transform="translate(484,406)" style="opacity: 1;"><rect rx="0" ry="0" x="-118" y="-22" width="236" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-108,-12)"><foreignObject width="216" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBConnectionThreadSafe</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(755.5,226.5)" style="opacity: 1;"><rect rx="0" ry="0" x="-78.5" y="-22" width="157" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-68.5,-12)"><foreignObject width="137" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBConnection</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  每个连接可以创建一个对应的语句实例：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-5" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1388.5 724" style="max-width:1388.5px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-5 .node&gt;rect { ; }
#mermaid-diagram-5 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-5 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-5 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-5 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph2" transform="translate(605.5,161)" style="opacity: 1;"><rect width="1072" height="94" x="-536" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-5Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph1" transform="translate(536.125,305)" style="opacity: 1;"><rect width="1032.25" height="94" x="-516.125" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-5Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph0" transform="translate(854.5,543)" style="opacity: 1;"><rect width="988" height="94" x="-494" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-5Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M512,565L512,590L512,615L817.25,652.7794601711653" marker-end="url(#arrowhead534)" style="fill:none"></path><defs><marker id="arrowhead534" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M780,565L780,590L780,615L839.4414893617021,640" marker-end="url(#arrowhead535)" style="fill:none"></path><defs><marker id="arrowhead535" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1003.5,565L1003.5,590L1003.5,615L944.0585106382979,640" marker-end="url(#arrowhead536)" style="fill:none"></path><defs><marker id="arrowhead536" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1219.5,565L1219.5,590L1219.5,615L966.25,651.3165522501907" marker-end="url(#arrowhead537)" style="fill:none"></path><defs><marker id="arrowhead537" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M512,446L512,471L512,496L512,521" marker-end="url(#arrowhead538)" style="fill:none"></path><defs><marker id="arrowhead538" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M148,327L148,352L148,377L350.5,403.14697802197804" marker-end="url(#arrowhead539)" style="fill:none"></path><defs><marker id="arrowhead539" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M388,327L388,352L388,377L453.95744680851067,402" marker-end="url(#arrowhead540)" style="fill:none"></path><defs><marker id="arrowhead540" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M636,327L636,352L636,377L570.0425531914893,402" marker-end="url(#arrowhead541)" style="fill:none"></path><defs><marker id="arrowhead541" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M946.25,327L946.25,352L946.25,377L673.5,406.52043753598156" marker-end="url(#arrowhead542)" style="fill:none"></path><defs><marker id="arrowhead542" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M234.5,183L234.5,208L234.5,233L234.5,258L535,293.1768368617684" marker-end="url(#arrowhead543)" style="fill:none"></path><defs><marker id="arrowhead543" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M516,183L516,208L516,233L516,258L579.8297872340426,283" marker-end="url(#arrowhead544)" style="fill:none"></path><defs><marker id="arrowhead544" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M756,183L756,208L756,233L756,258L692.1702127659574,283" marker-end="url(#arrowhead545)" style="fill:none"></path><defs><marker id="arrowhead545" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1000.5,183L1000.5,208L1000.5,233L1000.5,258L737,291.9766803840878" marker-end="url(#arrowhead546)" style="fill:none"></path><defs><marker id="arrowhead546" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M234.5,64L234.5,89L234.5,114L234.5,139" marker-end="url(#arrowhead547)" style="fill:none"></path><defs><marker id="arrowhead547" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="B1" transform="translate(234.5,161)" style="opacity: 1;"><rect rx="0" ry="0" x="-130" y="-22" width="260" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-120,-12)"><foreignObject width="240" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBDatasetStatementAbstract</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(516,161)" style="opacity: 1;"><rect rx="0" ry="0" x="-101.5" y="-22" width="203" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-91.5,-12)"><foreignObject width="183" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBUniDACStatement</div></foreignObject></g></g></g><g class="node cyan" id="B3" transform="translate(756,161)" style="opacity: 1;"><rect rx="0" ry="0" x="-88.5" y="-22" width="177" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-78.5,-12)"><foreignObject width="157" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBBDEStatement</div></foreignObject></g></g></g><g class="node cyan" id="B4" transform="translate(1000.5,161)" style="opacity: 1;"><rect rx="0" ry="0" x="-106" y="-22" width="212" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-96,-12)"><foreignObject width="192" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBNexusDBStatement</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(148,305)" style="opacity: 1;"><rect rx="0" ry="0" x="-93" y="-22" width="186" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-83,-12)"><foreignObject width="166" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBZEOSStatement</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(388,305)" style="opacity: 1;"><rect rx="0" ry="0" x="-97" y="-22" width="194" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-87,-12)"><foreignObject width="174" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBOracleStatement</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(636,305)" style="opacity: 1;"><rect rx="0" ry="0" x="-101" y="-22" width="202" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-91,-12)"><foreignObject width="182" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBDatasetStatement</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(946.25,305)" style="opacity: 1;"><rect rx="0" ry="0" x="-71" y="-22" width="142" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-61,-12)"><foreignObject width="122" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TODBCStatement</div></foreignObject></g></g></g><g class="node cyan" id="E1" transform="translate(512,543)" style="opacity: 1;"><rect rx="0" ry="0" x="-116.5" y="-22" width="233" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-106.5,-12)"><foreignObject width="213" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBStatementWithParams</div></foreignObject></g></g></g><g class="node cyan" id="E2" transform="translate(780,543)" style="opacity: 1;"><rect rx="0" ry="0" x="-101.5" y="-22" width="203" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-91.5,-12)"><foreignObject width="183" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBSQLite3Statement</div></foreignObject></g></g></g><g class="node cyan" id="E3" transform="translate(1003.5,543)" style="opacity: 1;"><rect rx="0" ry="0" x="-72" y="-22" width="144" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-62,-12)"><foreignObject width="124" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TOleDBStatement</div></foreignObject></g></g></g><g class="node cyan" id="E4" transform="translate(1219.5,543)" style="opacity: 1;"><rect rx="0" ry="0" x="-94" y="-22" width="188" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-84,-12)"><foreignObject width="168" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBProxyStatement</div></foreignObject></g></g></g><g class="node cyan" id="F" transform="translate(891.75,662)" style="opacity: 1;"><rect rx="0" ry="0" x="-74.5" y="-22" width="149" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-64.5,-12)"><foreignObject width="129" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBStatement</div></foreignObject></g></g></g><g class="node cyan" id="D" transform="translate(512,424)" style="opacity: 1;"><rect rx="0" ry="0" x="-161.5" y="-22" width="323" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-151.5,-12)"><foreignObject width="303" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBStatementWithParamsAndColumns</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(234.5,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-102.5" y="-22" width="205" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-92.5,-12)"><foreignObject width="185" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBFireDACStatement</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  在上面的层次结构中，<code>TSQLDBDatasetStatementAbstract</code>用于自定义类参数处理，例如FireDAC的<code>TADParams</code> （它以数组DML为特征）。</p>
<p>  还定义了一些专用的异常类：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-6" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1352.75 392" style="max-width:1352.75px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-6 .node&gt;rect { ; }
#mermaid-diagram-6 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-6 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-6 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-6 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph1" transform="translate(666.375,67)" style="opacity: 1;"><rect width="1292.75" height="94" x="-646.375" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-6Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph0" transform="translate(643,211)" style="opacity: 1;"><rect width="1181.5" height="94" x="-590.75" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-6Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M398.5,233L398.5,258L398.5,283L690.5,323.8452380952381" marker-end="url(#arrowhead610)" style="fill:none"></path><defs><marker id="arrowhead610" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M637.25,233L637.25,258L637.25,283L690.5,308.73521850899743" marker-end="url(#arrowhead611)" style="fill:none"></path><defs><marker id="arrowhead611" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M831.75,233L831.75,258L831.75,283L778.5,308.73521850899743" marker-end="url(#arrowhead612)" style="fill:none"></path><defs><marker id="arrowhead612" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1030.25,233L1030.25,258L1030.25,283L778.5,323.00760777683854" marker-end="url(#arrowhead613)" style="fill:none"></path><defs><marker id="arrowhead613" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M124.5,89L124.5,114L124.5,139L124.5,164L326,198.56386861313868" marker-end="url(#arrowhead614)" style="fill:none"></path><defs><marker id="arrowhead614" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M314.5,89L314.5,114L314.5,139L314.5,164L359.1808510638298,189" marker-end="url(#arrowhead615)" style="fill:none"></path><defs><marker id="arrowhead615" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M492,89L492,114L492,139L492,164L442.2659574468085,189" marker-end="url(#arrowhead616)" style="fill:none"></path><defs><marker id="arrowhead616" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M664.5,89L664.5,114L664.5,139L664.5,164L471,198.18984962406014" marker-end="url(#arrowhead617)" style="fill:none"></path><defs><marker id="arrowhead617" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M832.5,89L832.5,114L832.5,139L832.5,164L965.25,195.551201011378" marker-end="url(#arrowhead618)" style="fill:none"></path><defs><marker id="arrowhead618" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1030.25,89L1030.25,114L1030.25,139L1030.25,164L1030.25,189" marker-end="url(#arrowhead619)" style="fill:none"></path><defs><marker id="arrowhead619" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M1212.25,89L1212.25,114L1212.25,139L1212.25,164L1095.25,194.21428571428572" marker-end="url(#arrowhead620)" style="fill:none"></path><defs><marker id="arrowhead620" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A1" transform="translate(124.5,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-69.5" y="-22" width="139" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-59.5,-12)"><foreignObject width="119" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">EODBCException</div></foreignObject></g></g></g><g class="node cyan" id="A2" transform="translate(314.5,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-70.5" y="-22" width="141" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-60.5,-12)"><foreignObject width="121" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">EOleDBException</div></foreignObject></g></g></g><g class="node cyan" id="A3" transform="translate(492,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-57" y="-22" width="114" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-47,-12)"><foreignObject width="94" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLDBZEOS</div></foreignObject></g></g></g><g class="node cyan" id="A4" transform="translate(664.5,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-65.5" y="-22" width="131" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-55.5,-12)"><foreignObject width="111" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLDBRemote</div></foreignObject></g></g></g><g class="node cyan" id="A5" transform="translate(832.5,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-52.5" y="-22" width="105" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-42.5,-12)"><foreignObject width="85" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLDBBDE</div></foreignObject></g></g></g><g class="node cyan" id="A6" transform="translate(1030.25,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-66.5" y="-22" width="133" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-56.5,-12)"><foreignObject width="113" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLDBFireDAC</div></foreignObject></g></g></g><g class="node cyan" id="A7" transform="translate(1212.25,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-65.5" y="-22" width="131" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-55.5,-12)"><foreignObject width="111" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLDBUniDAC</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(398.5,211)" style="opacity: 1;"><rect rx="0" ry="0" x="-72.5" y="-22" width="145" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-62.5,-12)"><foreignObject width="125" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLDBException</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(637.25,211)" style="opacity: 1;"><rect rx="0" ry="0" x="-61" y="-22" width="122" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-51,-12)"><foreignObject width="102" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLDBOracle</div></foreignObject></g></g></g><g class="node cyan" id="B3" transform="translate(831.75,211)" style="opacity: 1;"><rect rx="0" ry="0" x="-83.5" y="-22" width="167" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-73.5,-12)"><foreignObject width="147" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLQueryException</div></foreignObject></g></g></g><g class="node cyan" id="B4" transform="translate(1030.25,211)" style="opacity: 1;"><rect rx="0" ry="0" x="-65" y="-22" width="130" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-55,-12)"><foreignObject width="110" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ESQLDBDataset</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(734.5,330)" style="opacity: 1;"><rect rx="0" ry="0" x="-44" y="-22" width="88" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-34,-12)"><foreignObject width="68" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Exception</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  查看<code>TestOleDB.dpr</code>示例程序，位于SQlite3文件夹中，使用我们的<code>SynOleDB</code> 单元连接到本地的MS SQL Server 2008 R2 Express edition，该版本将使用<code>Person.Address</code>表的JSON表示写入AdventureWorks2008R2示例数据库文件。</p>
<h3 id="toc_7">8.1.6. ISQLDBRows接口<a class="vnote-anchor" href="#toc_7" data-anchor-icon="#"></a></h3>
<p>  最简单的是保持在TSQLDBConnectionProperties级别，使用这个实例的<code>Execute()</code> 方法，并通过<code>ISQLDBRows</code>接口访问所有返回的数据。它将以抽象的方式自动建立到数据库的线程安全的连接。</p>
<p>  <code>SynDB.pas</code>的典型用法包括：</p>
<ul>
<li>初始化一个共享的<code>TSQLDBConnectionProperties</code>实例；</li>
<li>直接从这个实例的<code>Execute*()</code>方法执行语句。</li>
</ul>
<p>  定义数据库连接非常简单：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">var</span> Props: TSQLDBConnectionProperties;
 ...
  Props := TOleDBMSSQLConnectionProperties.Create(<span class="hljs-string">'.\\SQLEXPRESS'</span>,<span class="hljs-string">'AdventureWorks2008R2'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
  <span class="hljs-keyword">try</span>
    UseProps(Props);
  <span class="hljs-keyword">finally</span>
    Props.Free;
  <span class="hljs-keyword">end</span>;
</code></pre>
<p>  根据<code>TSQLDBConnectionProperties</code>子类的不同，输入参数也有所不同。请参阅文档中每个类的<code>Create() constructor</code>，以便按照要求设置所有参数。</p>
<p>  然后，任何子代码都可以执行任何SQL请求，具有可选的绑定参数，如下所示：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">UseProps</span><span class="hljs-params">(Props: TSQLDBConnectionProperties)</span>;</span>
<span class="hljs-keyword">var</span> I: ISQLDBRows;
<span class="hljs-keyword">begin</span>
  I := Props.Execute(<span class="hljs-string">'select * from Sales.Customer where AccountNumber like ?'</span>,[<span class="hljs-string">'AW000001%'</span>]);
  <span class="hljs-keyword">while</span> I.Step <span class="hljs-keyword">do</span>
    assert(Copy(I[<span class="hljs-string">'AccountNumber'</span>],<span class="hljs-number">1</span>,<span class="hljs-number">8</span>)=<span class="hljs-string">'AW000001'</span>);
<span class="hljs-keyword">end</span>;
</code></pre>
<p>  在这个过程中，没有定义<code>TSQLDBStatement</code>，也不需要添加<code>try ... finally Query.Free; end;</code>语句块。</p>
<p>  事实上，<code>MyConnProps.Execute</code>方法将以<code>ISQLDBRows</code>的形式返回一个<code>TSQLDBStatement</code>实例，可以使用这些方法遍历结果行，并检索各个列值。在上面的代码中，<code>I['FirstName']</code>实际上会调用<code>I.Column[]</code>默认属性，该属性将以变体形式返回列值。您还有其他专用的方法，如<code>ColumnUTF8</code> 或<code>ColumnInt</code>，可以直接检索需要的数据。</p>
<p>  注意，当使用我们的<code>TSynLog</code>类记录日志时，所有绑定参数都将出现在SQL语句中。</p>
<h3 id="toc_8">8.1.7. 正确使用ISQLDBRows接口<a class="vnote-anchor" href="#toc_8" data-anchor-icon="#"></a></h3>
<p>  您可能已经注意到，在前面的代码示例中，我们使用了<code>UseProps()</code>子过程。这是有目的的。</p>
<p>  我们可以这样写一个小的测试：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">var</span> Props: TSQLDBConnectionProperties;
    I: ISQLDBRows;
 ...
  Props := TOleDBMSSQLConnectionProperties.Create(<span class="hljs-string">'.\\SQLEXPRESS'</span>,<span class="hljs-string">'AdventureWorks2008R2'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
  <span class="hljs-keyword">try</span>
    I := Props.Execute(<span class="hljs-string">'select * from Sales.Customer where AccountNumber like ?'</span>,[<span class="hljs-string">'AW000001%'</span>]);
    <span class="hljs-keyword">while</span> I.Step <span class="hljs-keyword">do</span>
      assert(Copy(I[<span class="hljs-string">'AccountNumber'</span>],<span class="hljs-number">1</span>,<span class="hljs-number">8</span>)=<span class="hljs-string">'AW000001'</span>);
  <span class="hljs-keyword">finally</span>
    Props.Free;
  <span class="hljs-keyword">end</span>;
<span class="hljs-keyword">end</span>;
</code></pre>
<p>  事实上，您不应该使用这种模式。这段代码将在运行时导致意外的访问冲突。</p>
<p>  在后台，编译器会生成一些隐含的代码来释放<code>I: ISQLDBRows</code>局部变量，如下所示：</p>
<pre><code class="lang-pascal hljs"> ...
  <span class="hljs-keyword">finally</span>
    Props.Free;
  <span class="hljs-keyword">end</span>;
  I := <span class="hljs-keyword">nil</span>; <span class="hljs-comment">// this is generated by the compiler, just before the final "end;"</span>
<span class="hljs-keyword">end</span>;
</code></pre>
<p>  因此，在<code>Props</code> 实例之后释放<code>ISQLDBRows</code>，将导致访问冲突。</p>
<p>  正确的写法是使用一个子函数（函数离开时释放局部<code>ISQLDBRows</code>），或者显式地释放接口变量：</p>
<pre><code class="lang-pascal hljs">    <span class="hljs-keyword">while</span> I.Step <span class="hljs-keyword">do</span>
      assert(Copy(I[<span class="hljs-string">'AccountNumber'</span>],<span class="hljs-number">1</span>,<span class="hljs-number">8</span>)=<span class="hljs-string">'AW000001'</span>);
  <span class="hljs-keyword">finally</span>
    I := <span class="hljs-keyword">nil</span>; <span class="hljs-comment">// release local variable</span>
    Props.Free;
  <span class="hljs-keyword">end</span>;
</code></pre>
<p>  当然，大多数情况下，您将全局初始化进程的<code>TSQLDBConnectionProperties</code>，然后在进程结束时释放它。每个请求都将在它自己的子方法中处理，因此将在<code>TSQLDBConnectionProperties</code>主实例之前释放。</p>
<p>  最后但最重要的是，您不应该在每次需要访问数据库时才创建<code>TSQLDBConnectionProperties</code>实例，这样您可能会丢失很多<code>SynDB</code>特性，比如每个线程连接池或语句缓存。</p>
<h3 id="toc_9">8.1.8. 后期绑定<a class="vnote-anchor" href="#toc_9" data-anchor-icon="#"></a></h3>
<p>  我们通过自定义变体时间实现了列值的后期绑定访问。它使用了Ole自动化的内部机制，访问列内容，就像访问本地对象属性所在的列名一样。</p>
<p>  查看Delphi代码就很清楚和明显：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">UseProps</span><span class="hljs-params">(Props: TSQLDBConnectionProperties)</span>;</span>
<span class="hljs-keyword">var</span> Row: Variant;
<span class="hljs-keyword">begin</span>
  <span class="hljs-keyword">with</span> Props.Execute(<span class="hljs-string">'select * from Sales.Customer where AccountNumber like ?'</span>,
    [<span class="hljs-string">'AW000001%'</span>],@Row) <span class="hljs-keyword">do</span>
    <span class="hljs-keyword">while</span> Step <span class="hljs-keyword">do</span>
      assert(Copy(Row.AccountNumber,<span class="hljs-number">1</span>,<span class="hljs-number">8</span>)=<span class="hljs-string">'AW000001'</span>);
<span class="hljs-keyword">end</span>;
</code></pre>
<p>  <code>Props.Execute</code>返回<code>ISQLDBRows</code>接口，因此上面的代码将初始化（或复用已有的）线程安全连接（OleDB使用每个线程模型），初始化一条语句，执行它，通过<code>Step</code>方法和<code>Row</code>变体访问行，通过<code>Row.AccountNumber</code>语句直接行检索列值。</p>
<p>  上述代码是完全安全的，所有内存都将通过<code>ISQLDBRows</code>接口的引用计数垃圾回收特性释放。您不需要添加任何<code>try..finally Free; end</code>代码。</p>
<p>  这就是神奇的Delphi后期绑定。我们的<code>SynBigTable</code>单元也提供了类似的特性。</p>
<p>  实际上，这段代码比使用标准属性的访问要慢，如下所示：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">while</span> Step <span class="hljs-keyword">do</span>
  assert(Copy(ColumnUTF8(<span class="hljs-string">'AccountNumber'</span>),<span class="hljs-number">1</span>,<span class="hljs-number">8</span>)=<span class="hljs-string">'AW000001'</span>);
</code></pre>
<p>  但是前一个版本使用了列名的后期绑定，这看起来更自然。</p>
<p>  当然，由于是后期绑定，编译器在编译时无法检查列名，如果源代码中的列名是错误的，则运行时才会触发错误。</p>
<p>  首先，让我们看看访问行内容的最快方式。</p>
<p>  在所有情况下，使用列名的文本版本（<code>'AccountNumber'</code>）比直接使用列索引要慢，即使我们的<code>SynDB.pas</code>库使用散列快速查找，下面的代码总是更快：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">var</span> Customer: Integer;
<span class="hljs-keyword">begin</span>
  <span class="hljs-keyword">with</span> Props.Execute(
    <span class="hljs-string">'select * from Sales.Customer where AccountNumber like ?'</span>,
    [<span class="hljs-string">'AW000001%'</span>],@Customer) <span class="hljs-keyword">do</span> <span class="hljs-keyword">begin</span>
    Customer := ColumnIndex(<span class="hljs-string">'AccountNumber'</span>);
    <span class="hljs-keyword">while</span> Step <span class="hljs-keyword">do</span>
      assert(Copy(ColumnString(Customer),<span class="hljs-number">1</span>,<span class="hljs-number">8</span>)=<span class="hljs-string">'AW000001'</span>);
  <span class="hljs-keyword">end</span>;
<span class="hljs-keyword">end</span>;
</code></pre>
<p>  但是，老实说，在分析之后，发现大部分时间都花在了<code>Step</code>方法上，尤其是<code>fRowSet.GetData</code>。实际上，使用上面的代码，我没有发现任何值得一提的速度增长。</p>
<p>  我们通过散列函数（即<code>TDynArrayHashed</code>）查找名称的目标非常好。</p>
<p>  相反，在分析之后发现基于Ole自动化的后期绑定要慢一些。事实上，<code>Row.AccountNumber</code>表达式调用了一个隐含的<code>DispInvoke</code>函数，该函数在多次调用时很慢。我们的<code>SynCommons.pas</code>单元能够深入VCL，并通过修补内存中的VCL代码，调用该函数的优化版本，其结果是速度非常接近直接的<code>Column['AccountNumber']</code>调用。</p>
<h3 id="toc_10">8.1.9. TDataset和SynDB<a class="vnote-anchor" href="#toc_10" data-anchor-icon="#"></a></h3>
<p>  因为我们的<code>SynDB.pas</code>单元不依赖于Delphi的<code>DB.pas</code>单元，其结果集不从<code>TDataset</code>继承。</p>
<p>  这样做的好处是，当从对象代码访问这些结果集时，它们会快得多。</p>
<p>  但缺点是，您不能在通常的VCL应用中使用它们。</p>
<p>  为了便于<code>SynDB.pas</code>与VCL组件的使用，可以从任何<code>SynDB</code>查询创建<code>TDataSet</code>结果集。</p>
<p>  您可以使用两种优化的TDataSet结果集：</p>
<table>
<thead>
<tr>
<th><strong>TDataSet</strong>类</th>
<th>操作</th>
<th>单元</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>TClientDataSet</code></td>
<td>读写</td>
<td><code>SynDBMidasVCL.pas</code></td>
<td>由于内存复制而变慢</td>
</tr>
<tr>
<td><code>TSynSQLStatementDataSet</code></td>
<td>只读</td>
<td><code>SynDBVCL.pas</code></td>
<td>直接映射，速度很快</td>
</tr>
</tbody>
</table>
<p>  因此，您可以将<code>SynDB</code>请求的结果赋给任何TDataSource，例如我们的<code>TSynSQLStatementDataSet</code>快速只读存储：</p>
<pre><code class="lang-pascal hljs">  ds1.DataSet.Free; <span class="hljs-comment">// release previous TDataSet</span>
  ds1.DataSet := ToDataSet(ds1,aProps.Execute(<span class="hljs-string">'select * from people'</span>,[]));
</code></pre>
<p>  或<code>TClientDataSet</code>类型的内存存储：</p>
<pre><code class="lang-pascal hljs">  ds1.DataSet.Free; <span class="hljs-comment">// release previous TDataSet</span>
  ds1.DataSet := ToClientDataSet(ds1,aProps.Execute(<span class="hljs-string">'select * from people'</span>,[]));
</code></pre>
<p>  参见示例“<code>17 - TClientDataset use</code>”了解更多关于使用此类<code>TDataSet</code>的信息，包括一些速度信息。您需要先运行<code>TestSQL3.dpr</code>回归测试，获得所需的SQlite3数据文件。</p>
<h3 id="toc_11">8.1.10. TQuery仿真类<a class="vnote-anchor" href="#toc_11" data-anchor-icon="#"></a></h3>
<p>  <code>SynDB.pas</code>单元提供了一个类似<code>TQuery</code>的类。这个类模拟通常的<code>TQuery</code>类，没有继承<code>DB.pas</code>及其缓慢的<code>TDataSet</code>。</p>
<p>  它模仿了基本的TQuery VCL方法，具有以下优点：</p>
<ul>
<li>没有从TDataset继承，但在<code>SynDB.pas</code> <code>ISQLDBStatement</code>结果集上有自己的轻量级实现，因此通常要快得多；</li>
<li>在使用名称访问字段和参数时更快，甚至快过索引；</li>
<li>Unicode支持，即使是使用Delphi以前的unicode版本，也能够独立于当前系统字符集以<code>WideString</code>的形式返回数据；</li>
<li>您仍然可以通过在<code>SynDBVCL.pas</code>中定义的<code>ToDataSet()</code>函数从<code>SynDB</code>的<code>TQuery</code>创建<code>TDataSet</code>。</li>
</ul>
<p>  当然，由于它不是<code>TDataSet</code>组件，所以不能直接使用它作为RAD代码的简单替代。</p>
<p>  但是，如果您的应用是以数据为中心，并且计划用一些类封装其业务逻辑，例如，如果它准备正确地实现OOP，而不是RAD，您仍然可以直接用TQuery仿真器替换现有代码：</p>
<pre><code class="lang-pascal hljs">  Q := TQuery.Create(aSQLDBConnection);
  <span class="hljs-keyword">try</span>
    Q.SQL.Clear; <span class="hljs-comment">// optional</span>
    Q.SQL.Add(<span class="hljs-string">'select * from DOMAIN.TABLE'</span>);
    Q.SQL.Add(<span class="hljs-string">'  WHERE ID_DETAIL=:detail;'</span>);
    Q.ParamByName(<span class="hljs-string">'DETAIL'</span>).AsString := <span class="hljs-string">'123420020100000430015'</span>;
    Q.Open;
    Q.First;    <span class="hljs-comment">// optional</span>
    <span class="hljs-keyword">while</span> <span class="hljs-keyword">not</span> Q.Eof <span class="hljs-keyword">do</span> <span class="hljs-keyword">begin</span>
      assert(Q.FieldByName(<span class="hljs-string">'id_detail'</span>).AsString=<span class="hljs-string">'123420020100000430015'</span>);
      Q.Next;
    <span class="hljs-keyword">end</span>;
    Q.Close;    <span class="hljs-comment">// optional</span>
  <span class="hljs-keyword">finally</span>
    Q.Free;
  <span class="hljs-keyword">end</span>;
</code></pre>
<p>  您应该使用TSQLDBStatement而不是这个包装器，但是使用这种TQuery兼容代码可以简化一些现有代码的升级，特别是对于遗留代码和现有项目。</p>
<p>  它将有助于避免使用弃用过时的BDE，生成更小的可执行文件，访问各种数据库而无需支付大笔费用，避免对一个很大的遗留应用重写大量的现有代码行，或者让你的旧应用与数据库通过普通的HTTP通信，而不需要安装任何RDBMS客户端。</p>
<h3 id="toc_12">8.1.11. 连接属性存储为JSON<a class="vnote-anchor" href="#toc_12" data-anchor-icon="#"></a></h3>
<p>  您可以使用<code>TSynConnectionDefinition</code>将连接属性作为JSON内容保存在内存或文件中。</p>
<p>  典型的存储内容可能是这样的：</p>
<pre><code class="lang-json hljs"> {
   <span class="hljs-attr">"Kind"</span>: <span class="hljs-string">"TSQLDBSQLite3ConnectionProperties"</span>,
   <span class="hljs-attr">"ServerName"</span>: <span class="hljs-string">"database.db3"</span>,
   <span class="hljs-attr">"DatabaseName"</span>: <span class="hljs-string">""</span>,
   <span class="hljs-attr">"UserID"</span>: <span class="hljs-string">""</span>,
   <span class="hljs-attr">"Password"</span>: <span class="hljs-string">"PtvlPA=="</span>
 }
</code></pre>
<p>  <code>“Kind”</code>参数将用于存储实际的<code>TSQLDBConnectionProperties</code>类名。因此，通过修改存储在JSON文本文件中的配置（无需重新编译应用程序），就可以在运行时轻松地从一个数据库切换到另一个数据库。注意，SynDB*的实现类单元应该编译到可执行文件中，如<code>SynDBSQLite3.pas</code>用于<code>TSQLDBSQLite3ConnectionProperties</code>或<code>SynDBZeos.pas</code>用于<code>TSQLDBZeosConnectionProperties</code>。</p>
<p>  要从本地JSON文件创建一个新的<code>TSQLDBConnectionProperties</code>实例，只需编写：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">var</span> Props: TSQLDBConnectionProperties;
 ...
  Props := TSQLDBConnectionProperties.CreateFromFile(<span class="hljs-string">'localDBsettings.json'</span>);
</code></pre>
<p>  为安全起见，密码被加密并编码为Base64，您可以使用<code>TSynConnectionDefinition</code>的<code>Password</code>和<code>PasswordPlain</code>属性来计算写到磁盘上的值。</p>
<p>  因为<code>TSynConnectionDefinition</code>是一个<code>TSynPersistent</code>类，所以可以将它嵌套到应用程序中包含所有设置的<code>TSynAutoCreateFields</code>实例中。</p>
<p>  然后<code>mORMot.pas</code>的<code>ObjectToJSON</code>/<code>ObjectToJSONFile</code>和<code>JSONToObject</code>/<code>JSONFileToObject</code>函数就可以将这些全局设置持久化到文件或数据库中。</p>
<p>  有关ORM/REST级上的类似特性，请参见<code>TSQLRest.CreateFrom()</code>，以及<code>mORMotDB.pas</code>中定义的函数<code>function TSQLRestCreateFrom( aDefinition: TSynConnectionDefinition)</code>，它创建一个普通的本地ORM的，如果<code>aDefinition.Kind</code>是一个<code>TSQLRest</code>类名；也可使用外部数据库存储的ORM，如果<code>aDefinition.Kind</code>是<code>TSQLDBConnectionProperties</code>类名。</p>
<h2 id="toc_13">8.2. SynDB客户端<a class="vnote-anchor" href="#toc_13" data-anchor-icon="#"></a></h2>
<p>  从<code>SynDB.pas</code>的逻辑视角来看，以下是数据库是如何访问的：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-7" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 914.5 440" style="max-width:914.5px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-7 .node&gt;rect { ; }
#mermaid-diagram-7 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-7 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-7 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-7 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph1" transform="translate(435,173)" style="opacity: 1;"><rect width="830" height="118" x="-415" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-7Text" style="text-anchor: middle;"> </text></g><g class="cluster" id="subGraph0" transform="translate(550.5,341)" style="opacity: 1;"><rect width="648" height="118" x="-324" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-7Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M202.5,52.14950166112957L84.5,89L84.5,114L84.5,151" marker-end="url(#arrowhead681)" style="fill:none"></path><defs><marker id="arrowhead681" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M216.27659574468086,64L195,89L195,114L195,151" marker-end="url(#arrowhead682)" style="fill:none"></path><defs><marker id="arrowhead682" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M267.5,62.78231292517007L308.5,89L308.5,114L308.5,151" marker-end="url(#arrowhead683)" style="fill:none"></path><defs><marker id="arrowhead683" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M267.5,50.10344827586207L423.5,89L423.5,114L423.5,151" marker-end="url(#arrowhead684)" style="fill:none"></path><defs><marker id="arrowhead684" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M267.5,46.95941558441558L543,89L543,114L543,151" marker-end="url(#arrowhead685)" style="fill:none"></path><defs><marker id="arrowhead685" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M267.5,45.50344036697248L671,89L671,114L671,139" marker-end="url(#arrowhead686)" style="fill:none"></path><defs><marker id="arrowhead686" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M630,179.58231292517007L303.5,232L303.5,257L303.5,282L303.5,319" marker-end="url(#arrowhead687)" style="fill:none"></path><defs><marker id="arrowhead687" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M630,182.6182902584493L419.5,232L419.5,257L419.5,282L419.5,319" marker-end="url(#arrowhead688)" style="fill:none"></path><defs><marker id="arrowhead688" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M630,191.46564885496184L540,232L540,257L540,282L540,319" marker-end="url(#arrowhead689)" style="fill:none"></path><defs><marker id="arrowhead689" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M673.5932203389831,207L675.5,232L675.5,257L675.5,282L675.5,307" marker-end="url(#arrowhead690)" style="fill:none"></path><defs><marker id="arrowhead690" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M712,191.46564885496184L802,232L802,257L802,282L802,319" marker-end="url(#arrowhead691)" style="fill:none"></path><defs><marker id="arrowhead691" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="B1" transform="translate(84.5,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-29.5" y="-22" width="59" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-19.5,-12)"><foreignObject width="39" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ZDBC</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(195,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-31" y="-22" width="62" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-21,-12)"><foreignObject width="42" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ODBC</div></foreignObject></g></g></g><g class="node cyan" id="B3" transform="translate(308.5,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">OleDB</div></foreignObject></g></g></g><g class="node cyan" id="B4" transform="translate(423.5,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle</div></foreignObject></g></g></g><g class="node cyan" id="B5" transform="translate(543,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQLite3</div></foreignObject></g></g></g><g class="node cyan" id="B6" transform="translate(671,173)" style="opacity: 1;"><rect rx="0" ry="0" x="-41" y="-34" width="82" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-31,-24)"><foreignObject width="62" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB.pas<br>TDataset</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(303.5,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-42" y="-22" width="84" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32,-12)"><foreignObject width="64" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">NexusDB</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(419.5,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-24" y="-22" width="48" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-14,-12)"><foreignObject width="28" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">BDE</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(540,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DBExpress</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(675.5,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-39" y="-34" width="78" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-29,-24)"><foreignObject width="58" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">FireDAC<br>AnyDAC</div></foreignObject></g></g></g><g class="node cyan" id="C5" transform="translate(802,341)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">UniDAC</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(235,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  当然，正如<code>SynDB</code>架构中所述，其实物理实现很复杂。<br>
  现在我们将详细介绍这些数据库连接如何实现<code>SynDB.pas</code>接口。</p>
<h3 id="toc_14">8.2.1. OleDB或ODBC的统一管理<a class="vnote-anchor" href="#toc_14" data-anchor-icon="#"></a></h3>
<p>  OleDB（对象链接和嵌入数据库，也写成OLE DB或OLE-DB）是一种由Microsoft设计的API，用于统一访问来自各种数据源的数据。</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-8" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1111 342" style="max-width:1111px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-8 .node&gt;rect { ; }
#mermaid-diagram-8 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-8 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-8 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-8 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph0" transform="translate(545.5,255)" style="opacity: 1;"><rect width="1051" height="94" x="-525.5" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-8Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M540.75,64L540.75,89L540.75,114" marker-end="url(#arrowhead730)" style="fill:none"></path><defs><marker id="arrowhead730" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M508.25,139.37010479867624L87.5,183L87.5,208L87.5,233" marker-end="url(#arrowhead731)" style="fill:none"></path><defs><marker id="arrowhead731" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M508.25,140.58364591147787L207.5,183L207.5,208L207.5,233" marker-end="url(#arrowhead732)" style="fill:none"></path><defs><marker id="arrowhead732" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M508.25,143.66624843161856L341.5,183L341.5,208L341.5,233" marker-end="url(#arrowhead733)" style="fill:none"></path><defs><marker id="arrowhead733" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M509.03723404255317,158L473,183L473,208L473,233" marker-end="url(#arrowhead734)" style="fill:none"></path><defs><marker id="arrowhead734" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M572.4627659574468,158L608.5,183L608.5,208L608.5,233" marker-end="url(#arrowhead735)" style="fill:none"></path><defs><marker id="arrowhead735" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M573.25,143.2479240806643L751.5,183L751.5,208L751.5,233" marker-end="url(#arrowhead736)" style="fill:none"></path><defs><marker id="arrowhead736" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M573.25,140.48934606906687L881,183L881,208L881,233" marker-end="url(#arrowhead737)" style="fill:none"></path><defs><marker id="arrowhead737" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M573.25,139.31165311653118L1002,183L1002,208L1002,233" marker-end="url(#arrowhead738)" style="fill:none"></path><defs><marker id="arrowhead738" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="C1" transform="translate(87.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(207.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MS SQL</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(341.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Jet/Access</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(473,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-35" y="-22" width="70" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-25,-12)"><foreignObject width="50" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MySQL</div></foreignObject></g></g></g><g class="node cyan" id="C5" transform="translate(608.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-50.5" y="-22" width="101" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-40.5,-12)"><foreignObject width="81" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">PostgreSQL</div></foreignObject></g></g></g><g class="node cyan" id="C6" transform="translate(751.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-42.5" y="-22" width="85" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32.5,-12)"><foreignObject width="65" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Interbase</div></foreignObject></g></g></g><g class="node cyan" id="C7" transform="translate(881,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Firebird</div></foreignObject></g></g></g><g class="node cyan" id="C8" transform="translate(1002,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-34" y="-22" width="68" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-24,-12)"><foreignObject width="48" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Sybase</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(540.75,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(540.75,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">OleDB</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  当然，您可以使用Microsoft SQL Native客户端访问MS SQL Server 2005/2008/2012，Oracle也提供了一个本地OleDB驱动程序（但我们发现无论Oracle驱动程序，还是Microsoft版本，在blob方面都有问题）。不要忘记还有<em>Advantage Sybase OleDB</em>驱动程序等等…</p>
<p>  如果你想连接到MS SQL Server，我们强烈推荐使用<code>TOleDBMSSQL2012ConnectionProperties</code>类，对应<code>SQLNCLI11</code>，Microsoft®SQL Server®2012本地客户端的一部分，它可以连接到各种MS SQL Server修订版（包括MS SQL Server 2008），这样更稳定。你可以从http://www.microsoft.com/en-us/download/details.aspx?下载操作系统对应的<code>sqlncli.msi</code>。大多数情况下，您应该下载X64的<code>sqlncli.msi</code>，该安装包也支持安装32位版本的SQL Server Native Client，因此也适用于32位的Delphi可执行文件，X86包只适用于32位Windows系统。</p>
<p>  ODBC （Open DataBase Connectivity）是一种用于访问数据库管理系统（DBMS）的标准C语言中间件API。ODBC最初是在20世纪90年代初由Microsoft开发的，后来被OleDB取代。最近，微软正式宣布不支持OleDB，并敦促所有开发人员改用开放的、跨平台的ODBC API进行本地连接。又一次来自Micro$oft的糟糕的回退战略！<br>
<a href="http://blogs.msdn.com/b/sqlnativeclient/archive/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access.aspx">http://blogs.msdn.com/b/sqlnativeclient/archive/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access.aspx</a></p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-9" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1479 342" style="max-width:1479px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-9 .node&gt;rect { ; }
#mermaid-diagram-9 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-9 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-9 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-9 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph0" transform="translate(729.5,255)" style="opacity: 1;"><rect width="1419" height="94" x="-709.5" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-9Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M687.5,64L687.5,89L687.5,114" marker-end="url(#arrowhead783)" style="fill:none"></path><defs><marker id="arrowhead783" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.5,138.42833333333334L87.5,183L87.5,208L87.5,233" marker-end="url(#arrowhead784)" style="fill:none"></path><defs><marker id="arrowhead784" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.5,139.03541666666666L207.5,183L207.5,208L207.5,233" marker-end="url(#arrowhead785)" style="fill:none"></path><defs><marker id="arrowhead785" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.5,140.07552447552447L330,183L330,208L330,233" marker-end="url(#arrowhead786)" style="fill:none"></path><defs><marker id="arrowhead786" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.5,141.875L439.5,183L439.5,208L439.5,233" marker-end="url(#arrowhead787)" style="fill:none"></path><defs><marker id="arrowhead787" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.5,146.63503649635035L550.5,183L550.5,208L550.5,233" marker-end="url(#arrowhead788)" style="fill:none"></path><defs><marker id="arrowhead788" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M687.5,158L687.5,183L687.5,208L687.5,233" marker-end="url(#arrowhead789)" style="fill:none"></path><defs><marker id="arrowhead789" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.5,146.1888111888112L830.5,183L830.5,208L830.5,233" marker-end="url(#arrowhead790)" style="fill:none"></path><defs><marker id="arrowhead790" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.5,141.3467889908257L960,183L960,208L960,233" marker-end="url(#arrowhead791)" style="fill:none"></path><defs><marker id="arrowhead791" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.5,139.70266836086404L1081,183L1081,208L1081,233" marker-end="url(#arrowhead792)" style="fill:none"></path><defs><marker id="arrowhead792" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.5,138.78053435114504L1211.5,183L1211.5,208L1211.5,233" marker-end="url(#arrowhead793)" style="fill:none"></path><defs><marker id="arrowhead793" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.5,138.17950635751683L1356,183L1356,208L1356,233" marker-end="url(#arrowhead794)" style="fill:none"></path><defs><marker id="arrowhead794" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="C1" transform="translate(87.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(207.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MS SQL</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(330,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-35" y="-22" width="70" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-25,-12)"><foreignObject width="50" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MySQL</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(439.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-24.5" y="-22" width="49" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-14.5,-12)"><foreignObject width="29" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB2</div></foreignObject></g></g></g><g class="node cyan" id="C5" transform="translate(550.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-36.5" y="-22" width="73" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-26.5,-12)"><foreignObject width="53" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Infomix</div></foreignObject></g></g></g><g class="node cyan" id="C6" transform="translate(687.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-50.5" y="-22" width="101" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-40.5,-12)"><foreignObject width="81" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">PostgreSQL</div></foreignObject></g></g></g><g class="node cyan" id="C7" transform="translate(830.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-42.5" y="-22" width="85" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32.5,-12)"><foreignObject width="65" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Interbase</div></foreignObject></g></g></g><g class="node cyan" id="C8" transform="translate(960,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Firebird</div></foreignObject></g></g></g><g class="node cyan" id="C9" transform="translate(1081,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-34" y="-22" width="68" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-24,-12)"><foreignObject width="48" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Sybase</div></foreignObject></g></g></g><g class="node cyan" id="C10" transform="translate(1211.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Jet/Access</div></foreignObject></g></g></g><g class="node cyan" id="C11" transform="translate(1356,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-48" y="-22" width="96" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-38,-12)"><foreignObject width="76" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Advantage</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(687.5,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(687.5,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-31" y="-22" width="62" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-21,-12)"><foreignObject width="42" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ODBC</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  通过使用我们自己的OleDB和ODBC实现，我们将能够直接将OleDB或ODBC二进制行转换为JSON，而不需要临时转换为Delphi高级类型（如临时字符串或变体分配）。由于我们绕过了BDE/dbExpress/FireDAC/AnyDAC组件集引入的许多层，因此性能要比使用标准<code>TDataSet</code>或其他组件高得多。</p>
<p>  大多数OleDB / ODBC驱动是免费的（包括由数据库所有者维护的），少数驱动提供商需要付费许可证。</p>
<p>  值得指出的是，用于mORMot客户端-服务端架构时，OleDB或ODBC远程访问的对象持久性更希望实现服务器端的数据库实例访问。客户端可以通过标准HTTP进行通信，因此不需要任何特定的端口转发或其他IT配置就可以正常工作。</p>
<h3 id="toc_15">8.2.2. 基于ZDBC的ZEOS<a class="vnote-anchor" href="#toc_15" data-anchor-icon="#"></a></h3>
<h4 id="toc_16">8.2.2.1. mORMot最好的伙伴<a class="vnote-anchor" href="#toc_16" data-anchor-icon="#"></a></h4>
<p>  ZeosLib，又名Zeos，是一个开放源码库，它为Delphi、Kylix和Lazarus / FreePascal开发，提供许多数据库系统的本地访问。</p>
<p>  它是完全面向对象的，具有完全模块化的设计。它通过包装本地客户端库来连接数据库，并通过抽象层ZDBC来访问它们。最初，ZDBC是JDBC 2.0（Java数据库连接API）到对象Pascal的一个端口。从那时起，API略有扩展，但主要思想没有改变，所以正式的JDBC 2.0规范是ZDBC API的主要切入点。</p>
<p>  最新的7.x分支进行了深度重构，引入了新的方法和性能优化。事实上，我们与Michael （ZeosLib的主要贡献者）一起工作，以确保达到最优性能，所以mORMot和ZeosLib在读取或写入数据方面产生了令人印象深刻的协同作用。</p>
<p>  自框架的1.18版本以来，我们将ZeosLib直接集成到mORMot持久层，并直接访问ZDBC层。也就是说，我们的SynDBZeos单元不引用<code>DB.pas</code>单元，但可以直接访问ZDBC接口。</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-10" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1092 342" style="max-width:1092px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-10 .node&gt;rect { ; }
#mermaid-diagram-10 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-10 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-10 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-10 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph0" transform="translate(536,255)" style="opacity: 1;"><rect width="1032" height="94" x="-516" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-10Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M537,64L537,89L537,114" marker-end="url(#arrowhead833)" style="fill:none"></path><defs><marker id="arrowhead833" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M507.5,139.0845383759733L87.5,183L87.5,208L87.5,233" marker-end="url(#arrowhead834)" style="fill:none"></path><defs><marker id="arrowhead834" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M507.5,140.20789074355085L207.5,183L207.5,208L207.5,233" marker-end="url(#arrowhead835)" style="fill:none"></path><defs><marker id="arrowhead835" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M507.5,142.69806763285024L330,183L330,208L330,233" marker-end="url(#arrowhead836)" style="fill:none"></path><defs><marker id="arrowhead836" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M507.5,155.3916083916084L465.5,183L465.5,208L465.5,233" marker-end="url(#arrowhead837)" style="fill:none"></path><defs><marker id="arrowhead837" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M566.5,155.3916083916084L608.5,183L608.5,208L608.5,233" marker-end="url(#arrowhead838)" style="fill:none"></path><defs><marker id="arrowhead838" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M566.5,142.89800995024876L738,183L738,208L738,233" marker-end="url(#arrowhead839)" style="fill:none"></path><defs><marker id="arrowhead839" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M566.5,140.305900621118L859,183L859,208L859,233" marker-end="url(#arrowhead840)" style="fill:none"></path><defs><marker id="arrowhead840" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M566.5,139.12979683972912L980,183L980,208L980,233" marker-end="url(#arrowhead841)" style="fill:none"></path><defs><marker id="arrowhead841" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="C1" transform="translate(87.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(207.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MS SQL</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(330,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-35" y="-22" width="70" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-25,-12)"><foreignObject width="50" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MySQL</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(465.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-50.5" y="-22" width="101" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-40.5,-12)"><foreignObject width="81" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">PostgreSQL</div></foreignObject></g></g></g><g class="node cyan" id="C5" transform="translate(608.5,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-42.5" y="-22" width="85" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32.5,-12)"><foreignObject width="65" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Interbase</div></foreignObject></g></g></g><g class="node cyan" id="C6" transform="translate(738,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Firebird</div></foreignObject></g></g></g><g class="node cyan" id="C7" transform="translate(859,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-34" y="-22" width="68" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-24,-12)"><foreignObject width="48" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Sybase</div></foreignObject></g></g></g><g class="node cyan" id="C8" transform="translate(980,255)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQLite3</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(537,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(537,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-29.5" y="-22" width="59" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-19.5,-12)"><foreignObject width="39" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ZDBC</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  这种直接访问，绕过了VCL的<code>DB.pas</code>层及<code>TDataSet</code>瓶颈，非常接近我们的<code>SynDB.pas</code>设计。因此，ZeosLib是mORMot的首选类库。<code>SynDBZeos</code>单元也成为外部SQL数据库访问的优选。</p>
<h4 id="toc_17">8.2.2.2. 版本推荐<a class="vnote-anchor" href="#toc_17" data-anchor-icon="#"></a></h4>
<p>  我们建议您下载Zeos/ZDBC的7.2分支，它是撰写本文时的trunck分支。</p>
<p>  Zeos/ZDBC作者已经进行了深入的代码重构（非常感谢Michael，又名EgonHugeist！），他甚至考虑到了mORMot的需要，以提供最佳的性能和集成，如UTF-8内容处理。</p>
<p>  与之前的7.1版本相比，速度可以提高10倍以上，具体取决于数据库的后端和用例！</p>
<p>  在写入数据（即<em>Add/Update/Delete</em>操作）时，已经向Zeos/ZDBC 7.2分支添加了数组绑定支持，我们的SynDBZeos单元将通过检测<code>IZDatabaseInfo.SupportsArrayBindings</code>属性是否为true来使用它，目前Oracle和FireBird驱动程序就是这样。当按批处理模式处理时，我们的ORM从中受益，包括允许ZDBC创建优化的SQL。</p>
<p>  在检索单条记录情况下，读取性能非常高，远远高于其它基于<code>DB.pas</code>的数据库。如<code>TSQLDBZEOSStatement.ColumnsToJSON()</code>将避免很多临时内存分配，并能够直接从底层ZDBC二进制缓冲区创建JSON。</p>
<p>  如果你需要停留在7.2版本前，并希望使用SQlite3后端（但是你没有理由这样做，因为Zeos与SynDBSQlite3相比会很慢），对于Zeos&lt;7.2的<code>TZSQLiteCAPIPreparedStatement.ExecuteQueryPrepared()</code>和<code>TZSQLiteResultSet.FreeHandle</code>方法，您需要应用一些补丁，正如<code>SynDBZeos.pas</code>开头的注释所述。</p>
<h4 id="toc_18">8.2.2.3. 连接示例<a class="vnote-anchor" href="#toc_18" data-anchor-icon="#"></a></h4>
<p>  如果你想通过Zeos/ZDBC连接MySQL，请遵循以下步骤:</p>
<ul>
<li>从http://dev.mysql.com/downloads/connector/c下载“Windows (x86, 32位)，ZIP Archive”，然后解压文档：仅需要<code>libmysql.dll</code>，将其放入可执行文件夹中，或者放在系统路径中；</li>
<li>像平常一样连接：</li>
</ul>
<pre><code class="lang-pascal hljs"> fConnection := TSQLDBZEOSConnectionProperties.Create(
   <span class="hljs-string">'zdbc:mysql://192.168.2.60:3306/world?username=root;password=dev'</span>, <span class="hljs-string">''</span>, <span class="hljs-string">''</span>, <span class="hljs-string">''</span>);
</code></pre>
<ul>
<li>或者使用<code>URI()</code>方法：</li>
</ul>
<pre><code class="lang-pascal hljs"> fConnection := TSQLDBZEOSConnectionProperties.Create(
   TSQLDBZEOSConnectionProperties.URI(dMySQL,<span class="hljs-string">'192.168.2.60:3306'</span>),<span class="hljs-string">'root'</span>,<span class="hljs-string">'dev'</span>);
</code></pre>
<p>  对于PostgreSQL，Zeos驱动程序只需要<code>libpq.dll</code>和<code>libintl.dll</code>，如从http://www.enterprisedb.com/products.services-training/pgbindownload下载。</p>
<pre><code class="lang-pascal hljs"> PropsPostgreSQL := TSQLDBZEOSConnectionProperties.Create(
   TSQLDBZEOSConnectionProperties.URI(dPostgreSQL,<span class="hljs-string">'localhost:5432'</span>),
   <span class="hljs-string">'dbname'</span>,<span class="hljs-string">'username'</span>,<span class="hljs-string">'password'</span>);
</code></pre>
<p>  之后您可以使用<code>TSQLDBZEOSConnectionProperties.URI()</code>方法来生成需要的ZDBC连接字符串：</p>
<pre><code class="lang-pascal hljs"> PropsOracle := TSQLDBZEOSConnectionProperties.Create(
   TSQLDBZEOSConnectionProperties.URI(dOracle,<span class="hljs-string">''</span>,<span class="hljs-string">'oci64\oci.dll'</span>),
   <span class="hljs-string">'tnsname'</span>,<span class="hljs-string">'user'</span>,<span class="hljs-string">'pass'</span>);
 PropsFirebirdEmbedded := TSQLDBZEOSConnectionProperties.Create(
   TSQLDBZEOSConnectionProperties.URI(dFirebird,<span class="hljs-string">''</span>,<span class="hljs-string">'Firebird\fbembed.dll'</span>)
   <span class="hljs-string">'databasefilename'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">');
 PropsFirebirdRemote := TSQLDBZEOSConnectionProperties.Create(
   TSQLDBZEOSConnectionProperties.URI(dFirebird,'</span><span class="hljs-number">192.168</span>.<span class="hljs-number">1.10</span>:<span class="hljs-number">3055</span><span class="hljs-string">',
     '</span>c:\Firebird_2_5\bin\fbclient.dll<span class="hljs-string">',false),
  '</span><span class="hljs-number">3</span>camadas<span class="hljs-string">', '</span>sysdba<span class="hljs-string">', '</span>masterkey<span class="hljs-string">');
</span></code></pre>
<p>  请参阅<code>TSQLDBZEOSConnectionProperties</code>文档，了解这些语法的更多信息，以及这个伟大的开源库的可用功能。</p>
<h3 id="toc_19">8.2.3. 基于OCI的Oracle访问<a class="vnote-anchor" href="#toc_19" data-anchor-icon="#"></a></h3>
<p>  对于我们的框架，在实现<code>SynDBZeos</code>、<code>SynOleDB</code>、<code>SynDBODBC</code>单元的同时，也实现了<code>SynDBOracle</code>单元。它允许使用<em>Oracle Call Interface</em>直接访问任何远程Oracle服务器。</p>
<p>  Oracle Call Interface （OCI）是面向Oracle数据库的最全面、高性能、本机非托管的接口，它公开了Oracle数据库的全部功能。直接接入<code>oci.dll</code>库的接口是使用我们在<code>SynDB.pas</code>中引入的DB抽象类编写的。</p>
<p>  我们努力实现Oracle参考文档中关于<em>Building High Performance Drivers for Oracle</em>详细介绍的所有最佳实践模式。</p>
<p>  得到的速度相当惊人：对于所有请求，<code>SynDBOracle</code>的速度是使用Oracle提供的本地OleDB驱动程序的<code>SynOleDB</code>连接的3到5倍。与Oracle的官方ODBC驱动程序（基于<code>SynDBODBC</code>的连接）相比时，也发现了类似（甚至更糟糕）的速度损失。有关更详细的数字，请参见<a href="">数据访问基准测试</a>。</p>
<h4 id="toc_20">8.2.3.1. 优化客户端库<a class="vnote-anchor" href="#toc_20" data-anchor-icon="#"></a></h4>
<p>  值得指出的是，使用mORMot客户端-服务端架构时，Oracle数据库对象持久性只需要在服务器端访问Oracle实例，就像使用OleDB或ODBC一样。</p>
<p>  以下是<code>SynDBOracle</code>单元的主要特点：</p>
<ul>
<li>直接访问Oracle Call Interface （OCI）客户端，无需BDE、Midas、DBExpress及OleDB/ODBC等驱动程序；</li>
<li>从版本8开始，支持与Oracle OCI interface的各种版本协同工作；</li>
<li>针对Oracle 11g/12c的最新特性进行了优化（如使用本地<code>Int64</code>检索不带小数的NUMBER字段）；</li>
<li>能够免安装Oracle客户端，无需安装应用程序（通过文件/文件夹复制安装）；</li>
<li>原生Unicode（使用内部UTF-8编码），适用于所有版本的Delphi，并对每个数据库字符集进行特殊处理；</li>
<li>努力实现Oracle客户端各个版本的最佳性能；</li>
<li>适用于32位或64位架构的各种Windows版本（但OCI库必须使用与已编译的Delphi应用程序相同的版本，即当前版本仅支持32位）；</li>
<li>使用新的专用变体类型（类似于Ole自动化运行时属性）对列名进行后期绑定访问；</li>
<li>连接是多线程的，具有较低的内存和CPU资源消耗；</li>
<li>可以使用<code>'//host[:port]/[service_name]'</code>这样的连接字符串，避免使用<code>TNSNAME.ORA</code>文件；</li>
<li>使用行数组和BLOB获取，以获得最佳性能（ZEOS/ZDBC还没有这样处理）；</li>
<li>根据我们的实验，在客户端和服务端同时进行准备语句处理，如果可能的话，服务端缓存可以提高3倍的速度；</li>
<li>实现数组绑定，用于高速的批量修改，一次插入、更新或删除大量行；</li>
<li>实现绑定<code>TInt64DynArray</code>或<code>TRawUTF8DynArray</code>作为参数，如用于<code>SELECT .. IN</code>where子句；</li>
<li>游标支持，常用于处理存储过程和遗留代码。</li>
</ul>
<p>  当然，该单元与外部SQL数据库访问过程完美集成。如具有本地导出JSON方法的特性，这是ORM框架的主要输入，直接在批处理序列处理数组绑定。</p>
<h4 id="toc_21">8.2.3.2. 无需安装客户端的直接连接<a class="vnote-anchor" href="#toc_21" data-anchor-icon="#"></a></h4>
<p>  您可以使用Oracle提供的Oracle Instant Client （OIC）的最新版本，参见http://www.oracle.com/technetwork/database/features/instant-client，它允许在不安装标准巨大的Oracle客户机和配置ORACLE_HOME的情况下运行客户端应用程序。</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-11" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 634 530" style="max-width:634px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-11 .node&gt;rect { ; }
#mermaid-diagram-11 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-11 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-11 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-11 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M88,76L88,125L88,162" marker-end="url(#arrowhead864)" style="fill:none"></path><defs><marker id="arrowhead864" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M88,230L88,267L88,304" marker-end="url(#arrowhead865)" style="fill:none"></path><defs><marker id="arrowhead865" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M88,372L88,409L88,446" marker-end="url(#arrowhead866)" style="fill:none"></path><defs><marker id="arrowhead866" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M290.5,76L290.5,125L290.5,162" marker-end="url(#arrowhead867)" style="fill:none"></path><defs><marker id="arrowhead867" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M290.5,230L290.5,267L290.5,316" marker-end="url(#arrowhead868)" style="fill:none"></path><defs><marker id="arrowhead868" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M509.5,88L509.5,125L509.5,174" marker-end="url(#arrowhead869)" style="fill:none"></path><defs><marker id="arrowhead869" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(88,409)" style="opacity: 1;"><g transform="translate(-23,-12)" class="label"><foreignObject width="46" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">TCP/IP</span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(290.5,267)" style="opacity: 1;"><g transform="translate(-23,-12)" class="label"><foreignObject width="46" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">TCP/IP</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(509.5,125)" style="opacity: 1;"><g transform="translate(-23,-12)" class="label"><foreignObject width="46" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">TCP/IP</span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A1" transform="translate(88,54)" style="opacity: 1;"><rect rx="0" ry="0" x="-68" y="-22" width="136" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-58,-12)"><foreignObject width="116" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">RAD Application</div></foreignObject></g></g></g><g class="node cyan" id="A2" transform="translate(88,196)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-34" width="93" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-24)"><foreignObject width="73" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DBExpress<br>or BDE</div></foreignObject></g></g></g><g class="node cyan" id="A3" transform="translate(88,338)" style="opacity: 1;"><rect rx="0" ry="0" x="-55" y="-34" width="110" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-45,-24)"><foreignObject width="90" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">installed<br>Oracle Client</div></foreignObject></g></g></g><g class="node cyan" id="A4" transform="translate(88,468)" style="opacity: 1;"><rect rx="0" ry="0" x="-57" y="-22" width="114" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-47,-12)"><foreignObject width="94" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle Server</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(290.5,54)" style="opacity: 1;"><rect rx="0" ry="0" x="-84.5" y="-22" width="169" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-74.5,-12)"><foreignObject width="149" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">mORMot Application</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(290.5,196)" style="opacity: 1;"><rect rx="0" ry="0" x="-55" y="-34" width="110" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-45,-24)"><foreignObject width="90" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">installed<br>Oracle Client</div></foreignObject></g></g></g><g class="node cyan" id="B3" transform="translate(290.5,338)" style="opacity: 1;"><rect rx="0" ry="0" x="-57" y="-22" width="114" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-47,-12)"><foreignObject width="94" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle Server</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(509.5,54)" style="opacity: 1;"><rect rx="0" ry="0" x="-84.5" y="-34" width="169" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-74.5,-24)"><foreignObject width="149" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">mORMot Application<br>with OIC dlls</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(509.5,196)" style="opacity: 1;"><rect rx="0" ry="0" x="-57" y="-22" width="114" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-47,-12)"><foreignObject width="94" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle Server</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  只需在应用程序（可能是一个mORMot服务器）目录放入几个<code>dll</code>文件，它就可以以惊人的速度工作，并具有Oracle的所有特性（其他独立的直接Oracle访问库依赖于已废弃的Oracle 8协议）。</p>
<h4 id="toc_22">8.2.3.3. Oracle Wallet支持<a class="vnote-anchor" href="#toc_22" data-anchor-icon="#"></a></h4>
<p>  <strong><em>译者注：Oracle Wallet，Oracle从10gR2开始提供了wallet，用于解决用户认证信息(用户名和密码)的存放问题，通过使用wallet可以实现无密码登录数据库，这样一来就不需要在应用程序中嵌入数据库密码(或者在配置文件中明文存放密码)，同时更加方便维护大量服务器的环境的数据库密码维护工作，因为可以直接分发wallet文件，实现批量修改密码。</em></strong></p>
<p>  连接数据库的密码凭据现在可以存储在客户端<em>Oracle Wallet</em>中，这是一个用于存储身份验证和签名凭据的安全软件容器。</p>
<p>  这种wallet的使用可以简化依赖密码凭据连接数据库的大规模部署。配置此功能后，应用程序代码、批处理作业和脚本不再需要嵌入用户名和密码。风险降低了，因为这样的密码不再显示地公开，而且在用户名或密码更改时无需更改应用程序代码，密码管理策略更容易执行。</p>
<p>  为了使用这个特性，在连接数据库之前设置<code>TSQLDBOracleConnectionProperties.UseWallet</code>为<code>true</code>。</p>
<p>  Wallet配置在服务端运行的计算机上执行。您必须执行一个完整的Oracle客户端安装：OIC，<a href="">无需安装客户端的直接连接</a>是不允许访问wallet身份验证的。</p>
<p>  创建Wallet的步骤：</p>
<p>  1) 为wallet创建一个文件夹：</p>
<pre><code class="lang-sh hljs">&gt; mkdir c:\OraWallets
</code></pre>
<p>  2) 在命令行使用以下语法在客户端创建wallet：</p>
<pre><code class="lang-sh hljs">&gt; mkstore -wrl c:\OraWallets -create
</code></pre>
<p>  Oracle会询问设置wallet主密码，一定要记住！</p>
<p>  3) 在命令行使用以下语法在wallet中创建数据库连接凭证：</p>
<pre><code class="lang-sh hljs"> mkstore -wrl c:\OraWallets -createCredential TNS_alias_name_from_tnsnames_ora username password
</code></pre>
<p>  其中<code>password</code>是数据库用户的密码。Oracle将要求您输入wallet密码，使用前面步骤中的主密码。</p>
<p>  4) 在客户端<code>sqlnet.ora</code>文件中，添加<code>WALLET_LOCATION</code>参数并将其设置为wallet的目录，并设置<code>SQLNET.WALLET_OVERRIDE</code>参数为<code>TRUE</code>：</p>
<pre><code class="hljs">SQLNET.WALLET_OVERRIDE = TRUE
WALLET_LOCATION =
  (SOURCE =
    (METHOD = FILE)
    (METHOD_DATA =
  (DIRECTORY = c:\OraWallets)
  )
)
</code></pre>
<p>  您不能在数据库有wallet时删除它，您需要通过以下命令删除wallet凭证：</p>
<pre><code class="lang-sh hljs">mkstore -wrl wallet_location -deleteCredential db_alias
</code></pre>
<p>  Oracle将要求输入wallet密码，使用与创建wallet时相同的密码。</p>
<p>  请注意，如果您更喜欢使用GUI工具进行数据库管理，那么在数据库发行版中还可以使用<em>Oracle Wallet Manager</em>工具。<br>
  参见https://docs.oracle.com/cd/B28359_01/network.111/b28530/asowalet.htm</p>
<h3 id="toc_23">8.2.4. SQLite3<a class="vnote-anchor" href="#toc_23" data-anchor-icon="#"></a></h3>
<p>  我们的ORM框架封装了一个高效的SQLite3，可以静态（即在<code>exe</code>中）连接SQLite3引擎，也可以从外部<code>SQLite3.dll</code>连接SQLite3引擎。</p>
<p>  从我们的<code>SynDB.pas</code>数据库抽象类调用<code>SynSQLite3.pas</code>单元很容易。添加另一个这样的数据库只是一个非常轻量的层，它通过<code>SynDBSQLite3.pas</code>单元实现。</p>
<p>  如果希望将SQLite3引擎链接到项目可执行文件，请确保您的<code>uses</code>子句引用了<code>SynSQLite3Static.pas</code>单元。否则，定义一个<code>TSQLite3LibraryDynamic</code>实例来加载外部<code>sqlite3.dll</code>库：</p>
<pre><code class="lang-pascal hljs"> FreeAndNil(sqlite3); <span class="hljs-comment">// release any previous instance (e.g. static)</span>
 sqlite3 := TSQLite3LibraryDynamic.Create;
</code></pre>
<p>  要创建到已存在的SQLite3数据库文件的连接属性，请调用<code>TSQLDBSQLite3ConnectionProperties.Create</code>构造函数，将实际的SQLite3数据库文件作为ServerName参数，可以在<code>Password</code>中选择使用加密密码（自1.16之后版本可用），而忽略其它参数（<code>DataBaseName</code>，<code>UserID</code>）。</p>
<p>  这些类将实现一个内部语句缓存，就像用于<code>TSQLRestServerDB</code>的那样。在实践中，使用缓存可以使处理速度提高两倍（在处理小的请求时）。</p>
<p>  在mORMot ORM中您有两种访问SQLite3引擎的方法：</p>
<ul>
<li>要么直接从ORM核心；</li>
<li>或者是外部虚拟表。</li>
</ul>
<div class="mermaid-diagram"><svg id="mermaid-diagram-12" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 188.75 292" style="max-width:188.75px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-12 .node&gt;rect { ; }
#mermaid-diagram-12 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-12 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-12 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-12 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M98.29787234042553,64L116.25,89L116.25,114" marker-end="url(#arrowhead884)" style="fill:none"></path><defs><marker id="arrowhead884" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M66.70212765957447,64L48.75,89L48.75,136L48.75,183L66.70212765957447,208" marker-end="url(#arrowhead885)" style="fill:none"></path><defs><marker id="arrowhead885" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M116.25,158L116.25,183L98.29787234042553,208" marker-end="url(#arrowhead886)" style="fill:none"></path><defs><marker id="arrowhead886" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A" transform="translate(82.5,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-62.5" y="-22" width="125" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-52.5,-12)"><foreignObject width="105" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">mORMot ORM</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(116.25,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(82.5,230)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQLite3</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  如果您基于<em>mORMot</em>的应用仅是使用一个集中的SQLite3数据库，那么使用SynDBSQLite3外部表是没有意义的。但是，如果您希望将来能够连接到任何外部数据库，或者将数据分割到几个数据库文件中，那么使用外部SQLite3表就很有意义。当然，SQlite3引擎库本身将与内部和外部进程共享。</p>
<h3 id="toc_24">8.2.5. DB.pas库<a class="vnote-anchor" href="#toc_24" data-anchor-icon="#"></a></h3>
<p>  自框架的1.18修订版，引入了一个新的<code>SynDBDataset.pas</code>单元，支持各种基于<code>DB.pas</code>的数据库与我们的<code>SynDB.pas</code>类对接，并使用<code>TDataset</code>获取结果。由于<code>TDataset</code>的设计，相对于直接d的<code>SynDB.pas</code>连接（例如SQLite3或Oracle的结果），性能有所下降，但它也打开了各种可能的数据库访问。</p>
<p>  在mORMot源代码存储库的<code>SynDBDataset</code>子文件夹中已经发布了一些专用的驱动程序。到目前为止，已对接FireDAC（以前是AnyDAC）、UniDAC和BDE库，并且可以直接连接到NexusDB引擎。</p>
<p>  由于这里有许多可能的组合（请参阅[<a href="">SynDB架构</a>），所以欢迎反馈。由于我们的敏捷过程，我们将首先关注于我们需要和使用的驱动，这取决于mORMot用户要求的额外特性，并在可能的情况下提供包装器，或者至少提供测试功能，包括<em>Embarcadero</em>刚刚收购了AnyDAC并对其进行了改进并重新命名为FireDAC，以使其成为新的官方平台，DBExpress也将受益于该整合。</p>
<h4 id="toc_25">8.2.5.1. NexusDB访问<a class="vnote-anchor" href="#toc_25" data-anchor-icon="#"></a></h4>
<p>  NexusDB是一个“royalty-free、兼容SQL:2003核心、客户端/服务端和嵌入式数据库系统，具有与其他大量许可产品相竞争的特性”（供应商说的）。</p>
<p>  <strong><em>译者注：royalty-free，免版税。版税制是国际出版业通行的使用作品的支付方式，近年来我国也在逐渐实行。具体地讲，它是指著作权人因他人使用其作品而获得的一定货币份额。版税率一般多在6%到10%之间。以出版版税为例。出版版税的计算方法是，图书单价×图书印数或销量×版税率。RF是Royalty-Free的缩写，直接翻译成中文是“免版税”。用户在网上购买下载的图片，不需要按照其使用图片取得的收入的一定比例来向作者支付“版税”。而是一次性支付小额的使用费，便可以获得作者的授权使用。所以我们成为“RF授权”，具有“一次购买，多次使用”的特点。</em></strong></p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-13" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 144 316" style="max-width:144px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-13 .node&gt;rect { ; }
#mermaid-diagram-13 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-13 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-13 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-13 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M62,64L62,89L62,114" marker-end="url(#arrowhead898)" style="fill:none"></path><defs><marker id="arrowhead898" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M62,182L62,207L62,232" marker-end="url(#arrowhead899)" style="fill:none"></path><defs><marker id="arrowhead899" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A" transform="translate(62,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(62,148)" style="opacity: 1;"><rect rx="0" ry="0" x="-41" y="-34" width="82" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-31,-24)"><foreignObject width="62" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB.pas<br>TDataset</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(62,254)" style="opacity: 1;"><rect rx="0" ry="0" x="-42" y="-22" width="84" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32,-12)"><foreignObject width="64" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">NexusDB</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  我们使用并测试了免费的嵌入式版本，它非常适合像mORMot这样的客户端-服务端ORM框架，请参见http://www.nexusdb.com/support/index.php</p>
<h4 id="toc_26">8.2.5.2. FireDAC/AnyDAC库<a class="vnote-anchor" href="#toc_26" data-anchor-icon="#"></a></h4>
<p>  FireDAC是一组独特的通用数据访问组件，用于在Delphi上开发跨平台数据库应用程序。这实际上是一个第三方组件集，由Embarcadero从DA-SOFT Technologies收购（以前称为AnyDAC），并包含在Delphi XE3自后版本中。这是Delphi中用于高速数据库开发的新官方平台，支持现在已被弃用的DBExpress。</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-14" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1364.5 528" style="max-width:1364.5px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-14 .node&gt;rect { ; }
#mermaid-diagram-14 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-14 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-14 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-14 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M501,64L501,89L501,114" marker-end="url(#arrowhead955)" style="fill:none"></path><defs><marker id="arrowhead955" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M501,182L501,207L501,232" marker-end="url(#arrowhead956)" style="fill:none"></path><defs><marker id="arrowhead956" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M462,271.18243243243245L57,325L57,350" marker-end="url(#arrowhead957)" style="fill:none"></path><defs><marker id="arrowhead957" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M540,275.4303278688525L745,325L745,350" marker-end="url(#arrowhead958)" style="fill:none"></path><defs><marker id="arrowhead958" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M462,272.18548387096774L129,325L129,372L129,419L134.31914893617022,444" marker-end="url(#arrowhead959)" style="fill:none"></path><defs><marker id="arrowhead959" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M462,273.88013698630135L209,325L209,372L209,419L235.59574468085106,444" marker-end="url(#arrowhead960)" style="fill:none"></path><defs><marker id="arrowhead960" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M462,279.4758418740849L330.25,325L330.25,372L330.25,419L357.51063829787233,444" marker-end="url(#arrowhead961)" style="fill:none"></path><defs><marker id="arrowhead961" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M469.4491525423729,300L446.25,325L446.25,372L446.25,419L470.0531914893617,444" marker-end="url(#arrowhead962)" style="fill:none"></path><defs><marker id="arrowhead962" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M535.8644067796611,300L561.5,325L561.5,372L561.5,419L588.3617021276596,444" marker-end="url(#arrowhead963)" style="fill:none"></path><defs><marker id="arrowhead963" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M540,270.5859491778774L1002.75,325L1002.75,372L1002.75,419L1022.563829787234,444" marker-end="url(#arrowhead964)" style="fill:none"></path><defs><marker id="arrowhead964" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M540,269.749083503055L1114.75,325L1114.75,372L1114.75,419L1143.872340425532,444" marker-end="url(#arrowhead965)" style="fill:none"></path><defs><marker id="arrowhead965" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M540,269.11366711772666L1240,325L1240,372L1240,419L1266.8617021276596,444" marker-end="url(#arrowhead966)" style="fill:none"></path><defs><marker id="arrowhead966" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M714,374.6205035971223L189,419L162.40425531914894,444" marker-end="url(#arrowhead967)" style="fill:none"></path><defs><marker id="arrowhead967" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M714,375.35135135135135L310.25,419L282.98936170212767,444" marker-end="url(#arrowhead968)" style="fill:none"></path><defs><marker id="arrowhead968" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M714,376.57098039215686L426.25,419L402.4468085106383,444" marker-end="url(#arrowhead969)" style="fill:none"></path><defs><marker id="arrowhead969" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M714,379.15970515970514L541.5,419L514.6382978723404,444" marker-end="url(#arrowhead970)" style="fill:none"></path><defs><marker id="arrowhead970" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M714,392.3776223776224L673.5,419L640.7872340425532,444" marker-end="url(#arrowhead971)" style="fill:none"></path><defs><marker id="arrowhead971" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M749.6808510638298,394L755,419L755,444" marker-end="url(#arrowhead972)" style="fill:none"></path><defs><marker id="arrowhead972" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M776,381.43042071197414L899.5,419L899.5,444" marker-end="url(#arrowhead973)" style="fill:none"></path><defs><marker id="arrowhead973" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M776,376.16583273766975L1094.75,419L1065.627659574468,444" marker-end="url(#arrowhead974)" style="fill:none"></path><defs><marker id="arrowhead974" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M776,375.0673684210526L1220,419L1193.1382978723404,444" marker-end="url(#arrowhead975)" style="fill:none"></path><defs><marker id="arrowhead975" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M776,374.6228622862286L1300.5,419L1295.1808510638298,444" marker-end="url(#arrowhead976)" style="fill:none"></path><defs><marker id="arrowhead976" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A" transform="translate(501,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(501,148)" style="opacity: 1;"><rect rx="0" ry="0" x="-41" y="-34" width="82" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-31,-24)"><foreignObject width="62" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB.pas<br>TDataset</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(501,266)" style="opacity: 1;"><rect rx="0" ry="0" x="-39" y="-34" width="78" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-29,-24)"><foreignObject width="58" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">FireDAC<br>AnyDAC</div></foreignObject></g></g></g><g class="node cyan" id="D2" transform="translate(57,372)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQLite3</div></foreignObject></g></g></g><g class="node cyan" id="D1" transform="translate(745,372)" style="opacity: 1;"><rect rx="0" ry="0" x="-31" y="-22" width="62" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-21,-12)"><foreignObject width="42" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ODBC</div></foreignObject></g></g></g><g class="node cyan" id="E1" transform="translate(139,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle</div></foreignObject></g></g></g><g class="node cyan" id="E2" transform="translate(259,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MS SQL</div></foreignObject></g></g></g><g class="node cyan" id="E3" transform="translate(381.5,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-35" y="-22" width="70" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-25,-12)"><foreignObject width="50" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MySQL</div></foreignObject></g></g></g><g class="node cyan" id="E4" transform="translate(491,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-24.5" y="-22" width="49" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-14.5,-12)"><foreignObject width="29" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB2</div></foreignObject></g></g></g><g class="node cyan" id="E5" transform="translate(612,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Postgresql</div></foreignObject></g></g></g><g class="node cyan" id="E8" transform="translate(1040,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-42.5" y="-22" width="85" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32.5,-12)"><foreignObject width="65" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Interbase</div></foreignObject></g></g></g><g class="node cyan" id="E9" transform="translate(1169.5,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Firebird</div></foreignObject></g></g></g><g class="node cyan" id="E10" transform="translate(1290.5,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-34" y="-22" width="68" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-24,-12)"><foreignObject width="48" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Sybase</div></foreignObject></g></g></g><g class="node cyan" id="E6" transform="translate(755,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Jet/Access</div></foreignObject></g></g></g><g class="node cyan" id="E7" transform="translate(899.5,466)" style="opacity: 1;"><rect rx="0" ry="0" x="-48" y="-22" width="96" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-38,-12)"><foreignObject width="76" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Advantage</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  我们已经优化了<code>SynDB.pas</code>集成单元和mORMot持久层。如您可以通过ORM批处理过程，通过所谓的数组绑定，直接访问高速的FireDAC数组DML特性。</p>
<h4 id="toc_27">8.2.5.3. UniDAC库<a class="vnote-anchor" href="#toc_27" data-anchor-icon="#"></a></h4>
<p>  通用数据访问组件（UniDAC）是一个跨平台的组件库，提供Delphi对多个数据库的直接访问。参见http://www.devart.com/unidac</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-15" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1606 554" style="max-width:1606px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-15 .node&gt;rect { ; }
#mermaid-diagram-15 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-15 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-15 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-15 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph0" transform="translate(793,467)" style="opacity: 1;"><rect width="1546" height="94" x="-773" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-15Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M632,64L632,89L632,114" marker-end="url(#arrowhead1072)" style="fill:none"></path><defs><marker id="arrowhead1072" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M632,182L632,207L632,232" marker-end="url(#arrowhead1073)" style="fill:none"></path><defs><marker id="arrowhead1073" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M594.5,258.55426356589146L245,301L245,326" marker-end="url(#arrowhead1074)" style="fill:none"></path><defs><marker id="arrowhead1074" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M657.8617021276596,276L687.25,301L687.25,326" marker-end="url(#arrowhead1075)" style="fill:none"></path><defs><marker id="arrowhead1075" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M594.5,257.15718763994624L73.75,301L73.75,348L73.75,395L73.75,420L81.06382978723404,445" marker-end="url(#arrowhead1076)" style="fill:none"></path><defs><marker id="arrowhead1076" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M594.5,257.6377708978328L147.5,301L147.5,348L147.5,395L147.5,420L179.41489361702128,445" marker-end="url(#arrowhead1077)" style="fill:none"></path><defs><marker id="arrowhead1077" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M594.5,259.5164319248826L312.5,301L312.5,348L312.5,395L312.5,420L321.8085106382979,445" marker-end="url(#arrowhead1078)" style="fill:none"></path><defs><marker id="arrowhead1078" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M594.5,261.42887249736566L394.75,301L394.75,348L394.75,395L394.75,420L418.5531914893617,445" marker-end="url(#arrowhead1079)" style="fill:none"></path><defs><marker id="arrowhead1079" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M594.5,268.4467213114754L510,301L510,348L510,395L510,420L536.8617021276596,445" marker-end="url(#arrowhead1080)" style="fill:none"></path><defs><marker id="arrowhead1080" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M669.5,259.9796437659033L926.75,301L926.75,348L926.75,395L926.75,420L947.6276595744681,445" marker-end="url(#arrowhead1081)" style="fill:none"></path><defs><marker id="arrowhead1081" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M669.5,258.25467712733854L1046.25,301L1046.25,348L1046.25,395L1046.25,420L1078.2978723404256,445" marker-end="url(#arrowhead1082)" style="fill:none"></path><defs><marker id="arrowhead1082" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M669.5,257.2089212562585L1181.25,301L1181.25,348L1181.25,395L1181.25,420L1210.372340425532,445" marker-end="url(#arrowhead1083)" style="fill:none"></path><defs><marker id="arrowhead1083" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M669.5,256.4045020463847L1365,301L1365,348L1365,395L1365,420L1365,445" marker-end="url(#arrowhead1084)" style="fill:none"></path><defs><marker id="arrowhead1084" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M669.5,256.04466357308587L1494,301L1494,348L1494,395L1494,420L1494,445" marker-end="url(#arrowhead1085)" style="fill:none"></path><defs><marker id="arrowhead1085" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.25,350.6029477445288L127.5,395L127.5,420L106.22340425531915,445" marker-end="url(#arrowhead1086)" style="fill:none"></path><defs><marker id="arrowhead1086" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.25,351.0369984366858L207.5,395L207.5,420L207.5,445" marker-end="url(#arrowhead1087)" style="fill:none"></path><defs><marker id="arrowhead1087" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.25,352.6624L374.75,395L374.75,420L350.9468085106383,445" marker-end="url(#arrowhead1088)" style="fill:none"></path><defs><marker id="arrowhead1088" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.25,355.38656527249685L490,395L490,420L463.13829787234044,445" marker-end="url(#arrowhead1089)" style="fill:none"></path><defs><marker id="arrowhead1089" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M656.25,368.3776223776224L615.75,395L615.75,420L586.3617021276596,445" marker-end="url(#arrowhead1090)" style="fill:none"></path><defs><marker id="arrowhead1090" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M689.0053191489362,370L691,395L691,420L691,445" marker-end="url(#arrowhead1091)" style="fill:none"></path><defs><marker id="arrowhead1091" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.25,358.85288640595905L821.5,395L821.5,420L821.5,445" marker-end="url(#arrowhead1092)" style="fill:none"></path><defs><marker id="arrowhead1092" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.25,352.2979351032448L1026.25,395L1026.25,420L994.2021276595744,445" marker-end="url(#arrowhead1093)" style="fill:none"></path><defs><marker id="arrowhead1093" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.25,351.07383966244726L1161.25,395L1161.25,420L1132.127659574468,445" marker-end="url(#arrowhead1094)" style="fill:none"></path><defs><marker id="arrowhead1094" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M718.25,350.4152507252383L1290.5,395L1290.5,420L1261.5106382978724,445" marker-end="url(#arrowhead1095)" style="fill:none"></path><defs><marker id="arrowhead1095" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M245,370L245,395L245,420L225.0531914893617,445" marker-end="url(#arrowhead1096)" style="fill:none"></path><defs><marker id="arrowhead1096" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="E1" transform="translate(87.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle</div></foreignObject></g></g></g><g class="node cyan" id="E2" transform="translate(207.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MS SQL</div></foreignObject></g></g></g><g class="node cyan" id="E3" transform="translate(330,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-35" y="-22" width="70" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-25,-12)"><foreignObject width="50" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MySQL</div></foreignObject></g></g></g><g class="node cyan" id="E4" transform="translate(439.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-24.5" y="-22" width="49" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-14.5,-12)"><foreignObject width="29" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB2</div></foreignObject></g></g></g><g class="node cyan" id="E5" transform="translate(560.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Postgresql</div></foreignObject></g></g></g><g class="node cyan" id="E6" transform="translate(691,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-34" y="-22" width="68" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-24,-12)"><foreignObject width="48" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Sybase</div></foreignObject></g></g></g><g class="node cyan" id="E7" transform="translate(821.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Jet/Access</div></foreignObject></g></g></g><g class="node cyan" id="E8" transform="translate(966,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-48" y="-22" width="96" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-38,-12)"><foreignObject width="76" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Advantage</div></foreignObject></g></g></g><g class="node cyan" id="E9" transform="translate(1106.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-42.5" y="-22" width="85" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32.5,-12)"><foreignObject width="65" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Interbase</div></foreignObject></g></g></g><g class="node cyan" id="E10" transform="translate(1236,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Firebird</div></foreignObject></g></g></g><g class="node cyan" id="E11" transform="translate(1365,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-42" y="-22" width="84" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32,-12)"><foreignObject width="64" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">NexusDB</div></foreignObject></g></g></g><g class="node cyan" id="E12" transform="translate(1494,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQLite3</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(632,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(632,148)" style="opacity: 1;"><rect rx="0" ry="0" x="-41" y="-34" width="82" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-31,-24)"><foreignObject width="62" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB.pas<br>TDataset</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(632,254)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">UniDAC</div></foreignObject></g></g></g><g class="node cyan" id="D2" transform="translate(245,348)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">OleDB</div></foreignObject></g></g></g><g class="node cyan" id="D1" transform="translate(687.25,348)" style="opacity: 1;"><rect rx="0" ry="0" x="-31" y="-22" width="62" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-21,-12)"><foreignObject width="42" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ODBC</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  例如，要访问MySQL远程数据库，您应该使用：</p>
<pre><code class="lang-pascal hljs">PropsMySQL := TSQLDBUniDACConnectionProperties.Create(
  TSQLDBUniDACConnectionProperties.URI(dMySQL,<span class="hljs-string">'192.168.2.60:3306'</span>),
  <span class="hljs-string">'world'</span>, <span class="hljs-string">'root'</span>, <span class="hljs-string">'dev'</span>);
</code></pre>
<p>  与FireDAC相比，这个库提供了相当稳定的结果，但是缺少数组绑定特性。</p>
<h4 id="toc_28">8.2.5.4. BDE引擎<a class="vnote-anchor" href="#toc_28" data-anchor-icon="#"></a></h4>
<p>  Borland Database Engine （BDE）是Delphi早期版本附带的基于windows核心的数据库引擎和连接软件。即便它被弃用，自2000年以来被DBExpress所取代，但它仍然是一个工作解决方案，易于与<code>SynDB.pas</code>驱动进行接口。</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-16" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 1597 554" style="max-width:1597px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-16 .node&gt;rect { ; }
#mermaid-diagram-16 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-16 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-16 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-16 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph0" transform="translate(788.5,467)" style="opacity: 1;"><rect width="1537" height="94" x="-768.5" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-16Text" style="text-anchor: middle;"> </text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M844.75,64L844.75,89L844.75,114" marker-end="url(#arrowhead1169)" style="fill:none"></path><defs><marker id="arrowhead1169" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M844.75,182L844.75,207L844.75,232" marker-end="url(#arrowhead1170)" style="fill:none"></path><defs><marker id="arrowhead1170" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M820.75,259.2404181184669L629.5,301L629.5,326" marker-end="url(#arrowhead1171)" style="fill:none"></path><defs><marker id="arrowhead1171" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M820.75,255.46303501945525L73.75,301L73.75,348L73.75,395L73.75,420L81.06382978723404,445" marker-end="url(#arrowhead1172)" style="fill:none"></path><defs><marker id="arrowhead1172" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M820.75,255.62594594594594L151,301L151,348L151,395L151,420L174.13829787234042,445" marker-end="url(#arrowhead1173)" style="fill:none"></path><defs><marker id="arrowhead1173" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M868.75,257.1886925795053L1198.5,301L1198.5,348L1198.5,395L1198.5,420L1215.5212765957447,445" marker-end="url(#arrowhead1174)" style="fill:none"></path><defs><marker id="arrowhead1174" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M868.75,256.18498789346245L1361,301L1361,348L1361,395L1361,420L1361,445" marker-end="url(#arrowhead1175)" style="fill:none"></path><defs><marker id="arrowhead1175" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M868.75,255.7604369879048L1485.5,301L1485.5,348L1485.5,395L1485.5,420L1485.5,445" marker-end="url(#arrowhead1176)" style="fill:none"></path><defs><marker id="arrowhead1176" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M598.5,350.92276830491477L131,395L131,420L107.86170212765957,445" marker-end="url(#arrowhead1177)" style="fill:none"></path><defs><marker id="arrowhead1177" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M598.5,351.73350416399745L239.25,395L239.25,420L215.4468085106383,445" marker-end="url(#arrowhead1178)" style="fill:none"></path><defs><marker id="arrowhead1178" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M598.5,352.4761904761905L304,395L304,420L304,445" marker-end="url(#arrowhead1179)" style="fill:none"></path><defs><marker id="arrowhead1179" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M598.5,355.5103092783505L435.5,395L435.5,420L435.5,445" marker-end="url(#arrowhead1180)" style="fill:none"></path><defs><marker id="arrowhead1180" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M601.1808510638298,370L569,395L569,420L569,445" marker-end="url(#arrowhead1181)" style="fill:none"></path><defs><marker id="arrowhead1181" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M657.8191489361702,370L690,395L690,420L690,445" marker-end="url(#arrowhead1182)" style="fill:none"></path><defs><marker id="arrowhead1182" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M660.5,355.6282722513089L820.5,395L820.5,420L820.5,445" marker-end="url(#arrowhead1183)" style="fill:none"></path><defs><marker id="arrowhead1183" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M660.5,352.34277198211623L965,395L965,420L965,445" marker-end="url(#arrowhead1184)" style="fill:none"></path><defs><marker id="arrowhead1184" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M660.5,351.09341825902334L1100.5,395L1100.5,420L1100.5,445" marker-end="url(#arrowhead1185)" style="fill:none"></path><defs><marker id="arrowhead1185" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M660.5,350.22019047619045L1285.75,395L1285.75,420L1256.3617021276596,445" marker-end="url(#arrowhead1186)" style="fill:none"></path><defs><marker id="arrowhead1186" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="E1" transform="translate(87.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Oracle</div></foreignObject></g></g></g><g class="node cyan" id="E2" transform="translate(194.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-24.5" y="-22" width="49" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-14.5,-12)"><foreignObject width="29" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB2</div></foreignObject></g></g></g><g class="node cyan" id="E3" transform="translate(304,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-35" y="-22" width="70" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-25,-12)"><foreignObject width="50" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MySQL</div></foreignObject></g></g></g><g class="node cyan" id="E4" transform="translate(435.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Postgresql</div></foreignObject></g></g></g><g class="node cyan" id="E5" transform="translate(569,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Firebird</div></foreignObject></g></g></g><g class="node cyan" id="E6" transform="translate(690,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-34" y="-22" width="68" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-24,-12)"><foreignObject width="48" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Sybase</div></foreignObject></g></g></g><g class="node cyan" id="E7" transform="translate(820.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-46.5" y="-22" width="93" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-36.5,-12)"><foreignObject width="73" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Jet/Access</div></foreignObject></g></g></g><g class="node cyan" id="E8" transform="translate(965,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-48" y="-22" width="96" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-38,-12)"><foreignObject width="76" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Advantage</div></foreignObject></g></g></g><g class="node cyan" id="E9" transform="translate(1100.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-37.5" y="-22" width="75" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27.5,-12)"><foreignObject width="55" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">MS SQL</div></foreignObject></g></g></g><g class="node cyan" id="E10" transform="translate(1230.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-42.5" y="-22" width="85" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-32.5,-12)"><foreignObject width="65" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Interbase</div></foreignObject></g></g></g><g class="node cyan" id="E11" transform="translate(1361,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-38" y="-22" width="76" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-28,-12)"><foreignObject width="56" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Paradox</div></foreignObject></g></g></g><g class="node cyan" id="E12" transform="translate(1485.5,467)" style="opacity: 1;"><rect rx="0" ry="0" x="-36.5" y="-22" width="73" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-26.5,-12)"><foreignObject width="53" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Infomix</div></foreignObject></g></g></g><g class="node cyan" id="A" transform="translate(844.75,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-32.5" y="-22" width="65" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-22.5,-12)"><foreignObject width="45" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDB</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(844.75,148)" style="opacity: 1;"><rect rx="0" ry="0" x="-41" y="-34" width="82" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-31,-24)"><foreignObject width="62" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB.pas<br>TDataset</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(844.75,254)" style="opacity: 1;"><rect rx="0" ry="0" x="-24" y="-22" width="48" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-14,-12)"><foreignObject width="28" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">BDE</div></foreignObject></g></g></g><g class="node cyan" id="D" transform="translate(629.5,348)" style="opacity: 1;"><rect rx="0" ry="0" x="-31" y="-22" width="62" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-21,-12)"><foreignObject width="42" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ODBC</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  请不要在任何新项目上使用BDE ！<br>
  您最好切换到另一个访问库。</p>
<h3 id="toc_29">8.2.6. 通过HTTP远程访问<a class="vnote-anchor" href="#toc_29" data-anchor-icon="#"></a></h3>
<p>  <code>SynDBRemote.pas</code>单元允许您创建在远程HTTP服务器上执行SQL操作的数据库应用程序，而不用在数据库服务器上。您可以像任何其他<code>SynDB.pas</code>一样创建连接数据库，但传输将通过HTTP进行。因此，不需要在最终用户应用程序上部署数据库客户端：它只会使用HTTP请求，包括在Internet上也是如此。您可以使用<code>SynDB.pas</code>类的所有特性，可以轻松地实现一个优化的HTTP连接。</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-17" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 693 537" style="max-width:693px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-17 .node&gt;rect { ; }
#mermaid-diagram-17 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-17 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-17 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-17 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"><g class="cluster" id="subGraph4" transform="translate(581,295)" style="opacity: 1;"><rect width="144" height="118" x="-72" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-17Text" style="text-anchor: middle;"> Office 2</text></g><g class="cluster" id="subGraph3" transform="translate(336.5,366.5)" style="opacity: 1;"><rect width="305" height="261" x="-152.5" y="-130.5"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-116.5" fill="black" stroke="none" id="mermaid-diagram-17Text" style="text-anchor: middle;"> Server</text></g><g class="cluster" id="subGraph2" transform="translate(92,295)" style="opacity: 1;"><rect width="144" height="118" x="-72" y="-59"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-45" fill="black" stroke="none" id="mermaid-diagram-17Text" style="text-anchor: middle;"> Office 1</text></g><g class="cluster" id="subGraph1" transform="translate(431.5,67)" style="opacity: 1;"><rect width="144" height="94" x="-72" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-17Text" style="text-anchor: middle;"> Remote B</text></g><g class="cluster" id="subGraph0" transform="translate(267.5,67)" style="opacity: 1;"><rect width="144" height="94" x="-72" y="-47"></rect><g class="label"><g transform="translate(0,0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"></div></foreignObject></g></g><text x="0" y="-33" fill="black" stroke="none" id="mermaid-diagram-17Text" style="text-anchor: middle;"> Remote A</text></g></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M92,317L92,354L224,391L329.5,440.59760956175296" marker-end="url(#arrowhead1267)" style="fill:none"></path><defs><marker id="arrowhead1267" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M343.5,329L343.5,354L343.5,391L347.26271186440675,428" marker-end="url(#arrowhead1268)" style="fill:none"></path><defs><marker id="arrowhead1268" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M581,317L581,354L465,391L369.5,439.7835497835498" marker-end="url(#arrowhead1269)" style="fill:none"></path><defs><marker id="arrowhead1269" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M267.5,89L267.5,114L267.5,175L267.5,236L299.70338983050846,261" marker-end="url(#arrowhead1270)" style="fill:none"></path><defs><marker id="arrowhead1270" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M431.5,89L431.5,114L431.5,175L431.5,236L394.2118644067797,261" marker-end="url(#arrowhead1271)" style="fill:none"></path><defs><marker id="arrowhead1271" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="translate(224,391)" style="opacity: 1;"><g transform="translate(-20,-12)" class="label"><foreignObject width="40" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">direct</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(343.5,391)" style="opacity: 1;"><g transform="translate(-47,-12)" class="label"><foreignObject width="94" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">local network</span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(267.5,175)" style="opacity: 1;"><g transform="translate(-28,-36)" class="label"><foreignObject width="56" height="72"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">HTTP<br>HTTPS<br>Internet</span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="C3" transform="translate(581,295)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Client 3</div></foreignObject></g></g></g><g class="node cyan" id="S" transform="translate(343.5,295)" style="opacity: 1;"><rect rx="0" ry="0" x="-60" y="-34" width="120" height="68"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-50,-24)"><foreignObject width="100" height="48"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SynDBRemote<br>Server</div></foreignObject></g></g></g><g class="node cyan" id="D" transform="translate(349.5,450)" style="opacity: 1;"><rect rx="0" ry="0" x="-20" y="-22" width="40" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-10,-12)"><foreignObject width="20" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">DB</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(92,295)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Client 1</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(431.5,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Client 4</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(267.5,67)" style="opacity: 1;"><rect rx="0" ry="0" x="-37" y="-22" width="74" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-27,-12)"><foreignObject width="54" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Client 2</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  这个特性不是RESTful ORM的一部分，因此不使用<code>mORMot.pas</code>单元，它有自己的优化协议，使用增强的安全性（传输加密与用户身份验证和可选的HTTPS）和自动数据压缩。仅使用了<code>SynCrtSock.pas</code>单元的HTTP客户端和服务端类。</p>
<p>  由于您的应用程序可以同时使用<code>TDataSet</code>（请参阅<a href="">TDataSet和SynDB</a>）和<code>TQuery</code>（请参阅<a href="">TQuery仿真类</a>），这种新的传输方式可以轻松地将现有Delphi客户端-服务端应用程序转换为多层体系结构，而只需对源代码进行很小的改动。而对于您的新代码，您可以使用mORMot的RESTful功能切换到SOA/ORM设计。</p>
<p>  传输协议采用优化的二进制格式，同时在两端进行压缩、加密和数字签名，远程用户身份验证将通过挑战验证方案执行。如果需要，还可使用http.sys`内核模式发布HTTPS服务。</p>
<h4 id="toc_30">8.2.6.1. 服务端和客户端类<a class="vnote-anchor" href="#toc_30" data-anchor-icon="#"></a></h4>
<p>  为发布您的<code>SynDB.pas</code>连接，您需要初始化一个在<code>SynDBRemote.pas</code>中定义的<code>TSQLDBServer*</code>类：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-18" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 460 198" style="max-width:460px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-18 .node&gt;rect { ; }
#mermaid-diagram-18 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-18 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-18 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-18 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M108,64L108,89L167.8404255319149,114" marker-end="url(#arrowhead1279)" style="fill:none"></path><defs><marker id="arrowhead1279" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M333,64L333,89L273.1595744680851,114" marker-end="url(#arrowhead1280)" style="fill:none"></path><defs><marker id="arrowhead1280" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A" transform="translate(108,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-88" y="-22" width="176" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-78,-12)"><foreignObject width="156" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBServerHttpApi</div></foreignObject></g></g></g><g class="node cyan" id="B" transform="translate(220.5,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-89.5" y="-22" width="179" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-79.5,-12)"><foreignObject width="159" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBServerAbstract</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(333,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-87" y="-22" width="174" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-77,-12)"><foreignObject width="154" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBServerSockets</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  您可以基于<code>TSQLDBServerSockets</code>套接字API 定义HTTP服务器，也可以基于<code>TSQLDBServerHttpApi</code>类（仅Windows）定义更快、更稳定的HTTP服务，是基于Windows XP版本之后的<code>http.sys</code>内核模式的HTTP服务。</p>
<p>  对于客户端，您可以使用<code>SynDBRemote.pas</code>中定义下列类：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-19" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 999 292" style="max-width:999px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-19 .node&gt;rect { ; }
#mermaid-diagram-19 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-19 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-19 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-19 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M167,64L167,89L349,114.12187958883995" marker-end="url(#arrowhead1295)" style="fill:none"></path><defs><marker id="arrowhead1295" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M507.5,64L507.5,89L507.5,114" marker-end="url(#arrowhead1296)" style="fill:none"></path><defs><marker id="arrowhead1296" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M830,64L830,89L658.4574468085107,114" marker-end="url(#arrowhead1297)" style="fill:none"></path><defs><marker id="arrowhead1297" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M161,158L161,183L253.15425531914894,208" marker-end="url(#arrowhead1298)" style="fill:none"></path><defs><marker id="arrowhead1298" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M507.5,158L507.5,183L415.34574468085106,208" marker-end="url(#arrowhead1299)" style="fill:none"></path><defs><marker id="arrowhead1299" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A1" transform="translate(167,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-147" y="-22" width="294" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-137,-12)"><foreignObject width="274" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBWinHTTPConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(507.5,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-158.5" y="-22" width="317" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-148.5,-12)"><foreignObject width="297" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBHttpRequestConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="A2" transform="translate(507.5,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-143.5" y="-22" width="287" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-133.5,-12)"><foreignObject width="267" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBWinINetConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="A3" transform="translate(830,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-129" y="-22" width="258" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-119,-12)"><foreignObject width="238" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBCurlConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(161,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-138" y="-22" width="276" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-128,-12)"><foreignObject width="256" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBSocketConnectionProperties</div></foreignObject></g></g></g><g class="node cyan" id="C" transform="translate(334.25,230)" style="opacity: 1;"><rect rx="0" ry="0" x="-162.5" y="-22" width="325" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-152.5,-12)"><foreignObject width="305" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLDBHTTPConnectionPropertiesAbstract</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  注意，<code>TSQLDBHttpRequestConnectionProperties</code>是一个抽象的父类，因此不应该直接实例化它，而应该实例化它的派生实现。</p>
<p>  如您所见，您可以在普通套接字API客户端，<code>WinINet</code>或<code>WinHTTP</code>（在Windows下）客户端，<code>libcurl</code> API（主要在Linux上）之间进行选择。在Windows上，<code>TSQLDBWinHTTPConnectionProperties</code>类在Internet上更稳定，即使普通套接字在<code>localhost</code>上的<a href="">数据访问基准测试</a>给出的数据更好。</p>
<h4 id="toc_31">8.2.6.2. 通过HTTP发布一个SynDB连接<a class="vnote-anchor" href="#toc_31" data-anchor-icon="#"></a></h4>
<p>  可以这样定义HTTP服务：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">uses</span> SynDB, <span class="hljs-comment">// RDBMS core</span>
     SynDBSQLite3, SynSQLite3Static, <span class="hljs-comment">// static SQLite3 engine</span>
     SynDBRemote; <span class="hljs-comment">// for HTTP server</span>
 ...
<span class="hljs-keyword">var</span> Props: TSQLDBConnectionProperties;
    HttpServer: TSQLDBServerAbstract;
 ...
  Props := TSQLDBSQLite3ConnectionProperties.Create(<span class="hljs-string">'data.db3'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
  HttpServer := TSQLDBServerHttpApi.Create(Props,<span class="hljs-string">'syndbremote'</span>,<span class="hljs-string">'8092'</span>,<span class="hljs-string">'user'</span>,<span class="hljs-string">'pass'</span>);
</code></pre>
<p>  上面的代码将初始化到本地<code>data.db3</code>的SQlite3数据库连接（在Props变量中），然后通过<code>http.sys</code>的HTTP内核模式将服务发布到http://1.2.3.4:8092/syndbremote URI，假定服务器的IP是1.2.3.4。</p>
<p>  首先，使用<code>'user'</code>/<code>'pass'</code>要素定义了用户。注意，在我们的远程访问中，用户管理与RDBMS用户权限不一致：您最好在应用程序级别拥有自己的一组用户，以获得更高的安全性，并更好地与业务逻辑集成。如果想在RDBMS上创建新用户可能会很痛苦，但在<code>SynDBRemote.pas</code>侧，通过<code>Protocol.Authenticate</code>属性，管理远程用户身份验证则非常容易：</p>
<pre><code class="lang-pascal hljs">HttpServer.Protocol.Authenticate.AuthenticateUser(<span class="hljs-string">'toto'</span>,<span class="hljs-string">'pipo'</span>);
HttpServer.Protocol.Authenticate.AuthenticateUser(<span class="hljs-string">'toto2'</span>,<span class="hljs-string">'pipo2'</span>);
...
</code></pre>
<p>  您还可以依照<a href="">用户逐一认证</a>所述的方法共享mORMot的REST身份验证用户，方法是将缺省的<code>TSynAuthentication</code>类实例替换为<code>TSynAuthenticationRest</code>，就像在<code>mORMot.pas</code>中定义的那样。注意，同时使用<code>SynDBRemote</code>和mORMot的ORM/SOA听起来像是一种弱设计，但是在处理遗留代码和许多现有SQL语句时可能会有它的优点。</p>
<p>  URI应该进行注册，就像<code>http.sys</code> API所期望的那样。您可以使用系统管理员权限运行服务端，或者在安装应用程序中调用以下方法（就像我们在TestSQL3Register.dpr中所做的那样）：</p>
<pre><code class="lang-pascal hljs">THttpApiServer.AddUrlAuthorize(<span class="hljs-string">'syndbremote'</span>,<span class="hljs-string">'8092'</span>,false,<span class="hljs-string">'+'</span>);
</code></pre>
<h4 id="toc_32">8.2.6.3. 通过HTTP访问SynDB客户机<a class="vnote-anchor" href="#toc_32" data-anchor-icon="#"></a></h4>
<p>  在客户端，你可以这样写：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">uses</span> SynDB, <span class="hljs-comment">// RDBMS core</span>
     SynDBRemote; <span class="hljs-comment">// for HTTP client</span>
 ...
<span class="hljs-keyword">var</span> Props: TSQLDBConnectionProperties;
 ...
  Props := TSQLDBWinHTTPConnectionProperties.Create(<span class="hljs-string">'1.2.3.4:8092'</span>,<span class="hljs-string">'syndbremote'</span>,<span class="hljs-string">'user'</span>,<span class="hljs-string">'pass'</span>);
</code></pre>
<p>  如您所见，在客户端无需连接到<code>SynDBSQLite3.pas</code>、<code>SynSQLite3Static.pas</code>，只需要HTTP链接。不需要在应用程序中部署RDBMS客户端库，也不需要设置本地网络防火墙。</p>
<p>  我们在这里定义了一个具有'user' / 'pass'凭据的单个用户，但是您可以使用<code>TSQLDBServerAbstract</code>的<code>Protocol.Authenticate</code>属性在服务器端管理更多的用户。。</p>
<p>  然后，像往常一样使用连接执行您最喜欢的SQL：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">Test</span><span class="hljs-params">(Props: TSQLDBConnectionProperties)</span>;</span>
<span class="hljs-keyword">var</span> Stmt: ISQLDBRows;
<span class="hljs-keyword">begin</span>
  Stmt := Props.Execute(<span class="hljs-string">'select * from People where YearOfDeath=?'</span>,[<span class="hljs-number">1519</span>]);
  <span class="hljs-keyword">while</span> Stmt.Step <span class="hljs-keyword">do</span> <span class="hljs-keyword">begin</span>
    assert(Stmt.ColumnInt(<span class="hljs-string">'ID'</span>)&gt;<span class="hljs-number">0</span>);
    assert(Stmt.ColumnInt(<span class="hljs-string">'YearOfDeath'</span>)=<span class="hljs-number">1519</span>);
   <span class="hljs-keyword">end</span>;
<span class="hljs-keyword">end</span>;
</code></pre>
<p>  或者可以通过<code>SynDBVCL.pas</code>单元与VCL组件一起使用：</p>
<pre><code class="lang-pascal hljs">  ds1.DataSet.Free; <span class="hljs-comment">// release previous TDataSet</span>
  ds1.DataSet := ToDataSet(ds1,Props.Execute(<span class="hljs-string">'select * from people'</span>,[]));
</code></pre>
<p>  <code>TSynSQLStatementDataSet</code>结果集将直接映射<code>TSQLDBServer*</code>类返回的原始二进制数据，从而避免客户端应用程序中各种缓慢的数据编组，即使是大型内容。所有的数据都是由服务端计算和发送的：即使只在TDBGrid中显示一行，数据也是服务端传输的。事实上，只检索部分数据在本地网络上工作得很好，但在Internet上大量传输却不是一个好主意，因为太多的<code>ping</code>操作。因此，可以考虑添加一些筛选字段或一些应用程序级分页，以减少需要从<code>SynDBRemote</code>服务端检索的行数。</p>
<p>  如果服务端类定义了自己的<code>TSynAuthentication</code>类（如通过<code>TSynAuthenticationRest</code>使用REST用户和组），您应该创建自己的类，并覆盖以下方法:</p>
<pre><code class="lang-pascal hljs"><span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">TSQLDBWinHTTPConnectionPropertiesRest</span>.<span class="hljs-title">SetInternalProperties</span>;</span>
<span class="hljs-keyword">begin</span>
  <span class="hljs-keyword">if</span> fProtocol=<span class="hljs-keyword">nil</span> <span class="hljs-keyword">then</span>
    fProtocol := TSQLDBRemoteConnectionProtocol.Create(
      TSynAuthenticationRest.Create(<span class="hljs-keyword">nil</span>,[]));
  <span class="hljs-keyword">inherited</span>;
<span class="hljs-keyword">end</span>;
</code></pre>
<p>  该重载方法从<code>TSQLDBWinHTTPConnectionProperties</code>继承其所有行为，但使用ORM/SOA身份验证方案在服务端验证其用户。</p>
<h4 id="toc_33">8.2.6.4. 高级用例<a class="vnote-anchor" href="#toc_33" data-anchor-icon="#"></a></h4>
<p>  您可以使用这个远程连接特性，如将一个独立的共享SQLite3数据库升级为高性能、低维护的客户端-服务器数据库引擎。您可以在服务器端创建它：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">var</span> props: TSQLDBSQLite3ConnectionProperties;
    server: TSQLDBServerHttpApi;
...
  props := TSQLDBSQLite3ConnectionProperties.Create(<span class="hljs-string">'database.db3'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
  props.MainSQLite3DB.Synchronous := smOff;
  props.MainSQLite3DB.LockingMode := lmExclusive; <span class="hljs-comment">// tune the performance</span>
  server := TSQLDBServerHttpApi.Create(props,<span class="hljs-string">'syndbremote'</span>,<span class="hljs-string">'8092'</span>,<span class="hljs-string">'user'</span>,<span class="hljs-string">'password'</span>);
...
</code></pre>
<p>  您可以通过创建如下属性来共享现有的SQlite3数据库实例（如创建用于RESTful ORM的TSQLRestServerDB，请参阅<a href="">数据库层</a>）：</p>
<pre><code class="lang-pascal hljs">  props := TSQLDBSQLite3ConnectionProperties.Create(aRestServerDB.DB);
  server := TSQLDBServerHttpApi.Create(props,<span class="hljs-string">'syndbremote'</span>,<span class="hljs-string">'8092'</span>,<span class="hljs-string">'user'</span>,<span class="hljs-string">'password'</span>);
</code></pre>
<p>  当使用<code>http.sys</code>内核模式服务，如果数据库名称（即这里的<code>'syndbremote'</code>）与ORM表或方法服务不冲突，那么在普通ORM/SOA操作（对于纯粹的HTTP服务可能是80）和远程<code>SynDB</code>访问之间可以共享相同的IP端口。</p>
<p>  您还可以在服务器和服务端设置自己的<code>TSQLDBProxyConnectionProtocol</code>类来定制传输协议。</p>
<h4 id="toc_34">8.2.6.5. 与SynDBExplorer集成<a class="vnote-anchor" href="#toc_34" data-anchor-icon="#"></a></h4>
<p>  我们的<code>SynDBExplorer</code>工具能够将任何<code>SynDB</code>连接作为HTTP服务发布，或者通过HTTP连接它。这样可能非常方便，包括调试来说也是。</p>
<p>  要为现有数据库提供服务，只需像往常一样连接它，然后单击列表左下方的"<code>HTTP Server</code>"按钮。您可以调整服务端属性（HTTP端口、用于URI的数据库名称、用户凭据），然后单击"<code>Start</code>" 按钮。</p>
<p>  要连接到这个远程连接，请再运行一个SynDBExplorer实例。,使用"<code>Remote HTTP</code>"作为连接类型创建一个新的连接，并根据服务端设置相应的选项值，替换默认的"<code>localhost:8092</code>"（替换<code>localhost</code>为服务器IP以通过网络访问）为服务器名称、"<code>syndbremote</code>" 为数据库名称、"<code>synopse</code>"为用户名和密码。</p>
<p>  这样就能远程访问主服务器实例，就像通过常规客户端访问数据库一样。</p>
<p>  如果服务端数据库是SQLite3，那么您只需将这个本地引擎升级为一个真正的客户端-服务端数据库，您可能会对这样做的性能感到惊讶。</p>
<h4 id="toc_35">8.2.6.6. 别忘了还有mORMot！<a class="vnote-anchor" href="#toc_35" data-anchor-icon="#"></a></h4>
<p>  即使你可以使用这样的远程访问来实现一个n层架构，但您还是应该使用mORMot的客户端-服务端ORM，这样会提供更好的客户端-服务端集成，领域驱动设计模式的无感持久性，更好的OOP和SOLID模型设计，比原始SQL操作更高的性能。我们轻量化的mORMot不是简单在上面添加了数据传输层的ORM：它是一个完整的RESTful系统，是真正的SOA设计。</p>
<p>  但是为了将一些遗留的SQL代码集成到一个新的架构，<code>SynDBRemote.pas</code>有它的优点，可以与mORMot的高级特性结合使用。</p>
<p>  请注意，对于跨平台客户端，mORMot的ORM/SOA模式是一种更好的方法：不要在移动应用程序中使用SQL，而是使用服务，这样您就不需要对业务逻辑进行各种小的修改之后重新验证并将应用程序重新发布到商店！</p>
<h2 id="toc_36">8.3. SynDB ORM集成<a class="vnote-anchor" href="#toc_36" data-anchor-icon="#"></a></h2>
<h3 id="toc_37">8.3.1. 代码优先还是数据库优先<a class="vnote-anchor" href="#toc_37" data-anchor-icon="#"></a></h3>
<p>  在使用任何对象关系映射(ORM)时，您主要有两种可能：</p>
<ul>
<li>从头开始，即编写你的类，让ORM创建所有的数据库结构，它将直接反映对象的属性，这称之为“代码优先”;</li>
<li>使用现有数据库，然后在模型中定义类如何映射现有数据库结构，这是“数据库优先”。</li>
</ul>
<p>  我们的mORMot框架两条路径都支持，即使像其他ORM一样，代码优先听起来更直接。</p>
<h3 id="toc_38">8.3.2. 代码优先<a class="vnote-anchor" href="#toc_38" data-anchor-icon="#"></a></h3>
<p>  外部记录可以按照mORMot的ORM所要求的那样定义：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">type</span>
  <span class="hljs-title">TSQLRecordPeopleExt</span> = <span class="hljs-keyword">class</span>(TSQLRecord)
  <span class="hljs-keyword">private</span>
    fData: TSQLRawBlob;
    fFirstName: RawUTF8;
    fLastName: RawUTF8;
    fYearOfBirth: integer;
    fYearOfDeath: word;
    fLastChange: TModTime;
    fCreatedAt: TCreateTime;
  <span class="hljs-keyword">published</span>
    <span class="hljs-keyword">property</span> FirstName: RawUTF8 <span class="hljs-keyword">index</span> <span class="hljs-number">40</span> <span class="hljs-keyword">read</span> fFirstName <span class="hljs-keyword">write</span> fFirstName;
    <span class="hljs-keyword">property</span> LastName: RawUTF8 <span class="hljs-keyword">index</span> <span class="hljs-number">40</span> <span class="hljs-keyword">read</span> fLastName <span class="hljs-keyword">write</span> fLastName;
    <span class="hljs-keyword">property</span> Data: TSQLRawBlob <span class="hljs-keyword">read</span> fData <span class="hljs-keyword">write</span> fData;
    <span class="hljs-keyword">property</span> YearOfBirth: integer <span class="hljs-keyword">read</span> fYearOfBirth <span class="hljs-keyword">write</span> fYearOfBirth;
    <span class="hljs-keyword">property</span> YearOfDeath: word <span class="hljs-keyword">read</span> fYearOfDeath <span class="hljs-keyword">write</span> fYearOfDeath;
    <span class="hljs-keyword">property</span> LastChange: TModTime <span class="hljs-keyword">read</span> fLastChange <span class="hljs-keyword">write</span> fLastChange;
    <span class="hljs-keyword">property</span> CreatedAt: TCreateTime <span class="hljs-keyword">read</span> fCreatedAt <span class="hljs-keyword">write</span> fCreatedAt;
  <span class="hljs-keyword">end</span>;
</code></pre>
<p>  可见，这与内部ORM类没有区别：它继承了<code>TSQLRecord</code>，您也可以从<code>TSQLRecordMany</code>继承，以便使用<a href="">基于数据透视表的ORM实现</a>。</p>
<p>  唯一的区别是<code>index 40</code>属性定义了<code>FirstName</code>和<code>LastName</code>的发布属性：定义了创建文本列外部字段时使用的长度（UTF-16 <code>WideChar</code>或UTF-8编码）：</p>
<pre><code class="lang-pascal hljs">    <span class="hljs-keyword">property</span> FirstName: RawUTF8
      <span class="hljs-keyword">index</span> <span class="hljs-number">40</span>
      <span class="hljs-keyword">read</span> fFirstName <span class="hljs-keyword">write</span> fFirstName;
</code></pre>
<p>  事实上，SQLite3并不关心文本字段的长度，但是几乎所有其他数据库引擎都希望在表中定义<code>VARCHAR</code>列时指定最大长度。如果您没有在字段定义中指定任何长度（如没有定义<code>index ???</code>属性)， ORM将创建一个长度不受限制的列（如MS SQL Server的<code>varchar(max)</code>)。在这种情况下，代码可以工作，但是性能和磁盘效率可能会大大降低，通过CLOB访问的速度明显变慢。这种性能损失的唯一例外是SQlite3和PostgreSQL，对于它们，无限制的文本列的处理速度与<code>varchar(#)</code>一样快。</p>
<p>  默认情况下，ORM不会执行任何检查，来确保字段长度符合外部数据库中的列大小要求。您可以使用<code>TSQLRecordProperties</code>的<code>SetMaxLengthValidatorForTextFields()</code>或<code>SetMaxLengthFilterForTextFields()</code>方法在发送数据到外部数据库之前先执行验证和筛选规则，请参阅<a href="">筛选和验证</a>。</p>
<p>  以下是对于外部数据库的回归测试摘要：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-keyword">var</span> RExt: TSQLRecordPeopleExt;
  (...)
fProperties := TSQLDBSQLite3ConnectionProperties.Create(SQLITE_MEMORY_DATABASE_NAME,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
VirtualTableExternalRegister(fExternalModel,TSQLRecordPeopleExt,fProperties,<span class="hljs-string">'PeopleExternal'</span>);
aExternalClient := TSQLRestClientDB.Create(fExternalModel,<span class="hljs-keyword">nil</span>,<span class="hljs-string">'testExternal.db3'</span>,TSQLRestServerDB);
<span class="hljs-keyword">try</span>
  aExternalClient.Server.StaticVirtualTableDirect := StaticVirtualTableDirect;
  aExternalClient.Server.CreateMissingTables;
  Check(aExternalClient.Server.CreateSQLMultiIndex(
    TSQLRecordPeopleExt,[<span class="hljs-string">'FirstName'</span>,<span class="hljs-string">'LastName'</span>],false));
  (...)
  Start := aExternalClient.ServerTimestamp;
  (...)
  aID := aExternalClient.Add(RExt,true);
  (...)
  aExternalClient.Retrieve(aID,RExt);
  (...)
  aExternalClient.BatchStart(TSQLRecordPeopleExt);
  aExternalClient.BatchAdd(RExt,true);
  (...)
  Check(aExternalClient.BatchSend(BatchID)=HTTP_SUCCESS);
  Check(aExternalClient.TableHasRows(TSQLRecordPeopleExt));
  Check(aExternalClient.TableRowCount(TSQLRecordPeopleExt)=n);
  (...)
  RExt.FillPrepare(aExternalClient,<span class="hljs-string">'FirstName=? and LastName=?'</span>,
    [RInt.FirstName,RInt.LastName]); <span class="hljs-comment">// query will use index -&gt; fast :)</span>
  <span class="hljs-keyword">while</span> RExt.FillOne <span class="hljs-keyword">do</span> ...
  (...)
  Updated := aExternalClient.ServerTimestamp;
  (...)
  aExternalClient.Update(RExt);
  aExternalClient.UnLock(RExt);
  (...)
  aExternalClient.BatchStart(TSQLRecordPeopleExt);
  aExternalClient.BatchUpdate(RExt);
  (...)
  aExternalClient.BatchSend(BatchIDUpdate);
  (...)
  aExternalClient.Delete(TSQLRecordPeopleExt,i)
  (...)
  aExternalClient.BatchStart(TSQLRecordPeopleExt);
  aExternalClient.BatchDelete(i);
  (...)
  aExternalClient.BatchSend(BatchIDUpdate);
  (...)
  <span class="hljs-keyword">for</span> i := <span class="hljs-number">1</span> <span class="hljs-keyword">to</span> BatchID[high(BatchID)] <span class="hljs-keyword">do</span> <span class="hljs-keyword">begin</span>
    RExt.fLastChange := <span class="hljs-number">0</span>;
    RExt.CreatedAt := <span class="hljs-number">0</span>;
    RExt.YearOfBirth := <span class="hljs-number">0</span>;
    ok := aExternalClient.Retrieve(i,RExt,false);
    Check(ok=(i <span class="hljs-keyword">and</span> <span class="hljs-number">127</span>&lt;&gt;<span class="hljs-number">0</span>),<span class="hljs-string">'deletion'</span>);
    <span class="hljs-keyword">if</span> ok <span class="hljs-keyword">then</span> <span class="hljs-keyword">begin</span>
      Check(RExt.CreatedAt&gt;=Start);
      Check(RExt.CreatedAt&lt;=Updated);
      <span class="hljs-keyword">if</span> i <span class="hljs-keyword">mod</span> <span class="hljs-number">100</span>=<span class="hljs-number">0</span> <span class="hljs-keyword">then</span> <span class="hljs-keyword">begin</span>
        Check(RExt.YearOfBirth=RExt.YearOfDeath,<span class="hljs-string">'Update'</span>);
        Check(RExt.LastChange&gt;=Updated);
      <span class="hljs-keyword">end</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">begin</span>
        Check(RExt.YearOfBirth&lt;&gt;RExt.YearOfDeath,<span class="hljs-string">'Update'</span>);
        Check(RExt.LastChange&gt;=Start);
        Check(RExt.LastChange&lt;=Updated);
      <span class="hljs-keyword">end</span>;
    <span class="hljs-keyword">end</span>;
  <span class="hljs-keyword">end</span>;
  (...)
</code></pre>
<p>  如上可见，使用本地SQLite3引擎或远程数据库引擎没有区别。</p>
<p>  从客户端角度看，您只需调用通常的RESTful CRUD方法，即<code>Add() Retrieve() Update() UnLock() Delete()</code>，或更快的<code>Batch*()</code>修订，甚至如带有复杂WHERE子句的<code>FillPrepare</code>、服务端的<code>CreateSQLMultiIndex / CreateMissingTables</code>等高级方法。</p>
<p>  在远程数据库中创建表（<code>'CREATE table…’</code>SQL语句）是由框架在调用CreateMissingTables方法时执行，并根据数据库的要求（如SQLite3的文本将是Oracle的<code>NVARCHAR2</code>字段）使用适当的列属性。</p>
<p>  在外部数据库上创建的表如下：</p>
<div class="plantuml-diagram"><!--?xml version="1.0" encoding="UTF-8" standalone="no"?--><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentscripttype="application/ecmascript" contentstyletype="text/css" height="441px" preserveAspectRatio="none" style="width:250px;height:441px;" version="1.1" viewBox="0 0 250 441" width="250px" zoomAndPan="magnify" class="view-svg"><defs><filter height="300%" id="f1rgyqqputgfc5" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"></feGaussianBlur><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"></feColorMatrix><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"></feOffset><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"></feBlend></filter></defs><g><ellipse cx="122.7459" cy="95.5968" fill="#FEFECE" filter="url(#f1rgyqqputgfc5)" rx="108.7459" ry="87.5968" style="stroke: #A80036; stroke-width: 1.5;"></ellipse><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="99.2459" y="28.7355">ID : TID</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="49.2115" x2="196.2804" y1="31.8117" y2="31.8117"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="134" x="55.7459" y="51.8557">Data : TSQLRawBlob</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="24.9843" x2="220.5076" y1="58.9318" y2="58.9318"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="138" x="53.7459" y="78.9758">FirstName : RawUTF8</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="15.6475" x2="229.8444" y1="86.0519" y2="86.0519"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="137" x="54.2459" y="106.0959">LastName : RawUTF8</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="17.2113" x2="228.2806" y1="113.1721" y2="113.1721"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="130" x="57.7459" y="133.216">YearOfBirth : integer</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="30.221" x2="215.2709" y1="140.2922" y2="140.2922"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="125" x="60.2459" y="160.3361">YearOfDeath : word</text><ellipse cx="122.5967" cy="336.8774" fill="#FEFECE" filter="url(#f1rgyqqputgfc5)" rx="116.5967" ry="93.8774" style="stroke: #A80036; stroke-width: 1.5;"></ellipse><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="85" x="80.0967" y="268.22">ID : INTEGER</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="40.1685" x2="205.025" y1="271.2962" y2="271.2962"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="79" x="83.0967" y="291.3401">Data : BLOB</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="17.2346" x2="227.9589" y1="298.4163" y2="298.4163"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="177" x="34.0967" y="318.4602">FirstName : NVARCHAR(40)</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="7.8539" x2="237.3395" y1="325.5364" y2="325.5364"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="176" x="34.5967" y="345.5803">LastName : NVARCHAR(40)</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="8.6588" x2="236.5346" y1="352.6565" y2="352.6565"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="146" x="49.5967" y="372.7005">YearOfBirth : INTEGER</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="19.8861" x2="225.3074" y1="379.7766" y2="379.7766"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="155" x="45.0967" y="399.8206">YearOfDeath : INTEGER</text><!--MD5=[1aa3f81a3bd80cff712043234baebedb]
link UC1 to UC2--><path d="M122.5,183.304 C122.5,200.924 122.5,219.577 122.5,237.566 " fill="none" id="UC1->UC2" style="stroke: #A80036; stroke-width: 1.0;"></path><polygon fill="#A80036" points="122.5,242.621,126.5,233.621,122.5,237.621,118.5,233.621,122.5,242.621" style="stroke: #A80036; stroke-width: 1.0;"></polygon><!--MD5=[d5b086246061ef29e54c103673af85c9]
@startuml
usecase UC1 as "ID : TID
- -
Data : TSQLRawBlob
- -
FirstName : RawUTF8
- -
LastName : RawUTF8
- -
YearOfBirth : integer
- -
YearOfDeath : word“

usecase UC2 as "ID : INTEGER
- -
Data : BLOB
- -
FirstName : NVARCHAR(40)
- -
LastName : NVARCHAR(40)
- -
YearOfBirth : INTEGER
- -
YearOfDeath : INTEGER"


(UC1) - ->(UC2)
@enduml

PlantUML version 1.2019.12(Sun Nov 03 18:24:54 CST 2019)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Java Version: 13.0.1+9
Operating System: Windows 10
Default Encoding: GBK
Language: zh
Country: CN
--></g></svg></div>
<p>  唯一特别的指令是全局<code>VirtualTableExternalRegister()</code>函数,它必须运行在服务端（在客户端上运行它没有任何意义，因为客户端没有表，简单的说就是客户端不关心存储，这是服务端的事）。</p>
<p>  为了按预期工作，应该在<code>TSQLRestServer</code>构造函数之前调用<code>VirtualTableExternalRegister()</code>。当服务端初始化时，ORM服务器必须知道需要管理内部或外部数据库。在上面的代码中，<code>TSQLRestClientDB.Create()</code>将实例化它自己的嵌入式<code>TSQLRestServerDB</code>实例。</p>
<p>  注意，<code>TSQLRecordExternal.LastChange</code>字段被定义为TModTime：这样，每次记录更新时，都会存储当前日期和时间，也就是说，如每次的<code>aExternalClient.Add</code>和<code>aExternalClient.Update</code>调用。测试代码使用循环来检查<code>RExt.LastChange&gt;=Start</code>和<code>RExt.LastChange&lt;=Updated</code>，记录的时间是“服务器时间”，即当前服务器上的日期和时间，在外部数据库的情况下，是远程服务器的时间（在MS SQL将执行<code>select getdate()</code> 获取日期并插入<code>LastChange</code>）。为了获取服务端时间戳，应该调用<code>Start := aExternalClient.ServerTimestamp</code>而不是<code>TimeLogNow</code>本地时间函数。</p>
<p>  对<code>CreatedAt</code> 发布字段（定义为TCreateTime）也测试了类似的特性：它将在创建记录时自动设置为当前服务器时间（在修改时不会更改），这就是上述代码检查<code>RExt.CreatedAt&lt;=Updated</code>的目的。</p>
<h3 id="toc_39">8.3.3. 数据库优先<a class="vnote-anchor" href="#toc_39" data-anchor-icon="#"></a></h3>
<p>  正如前面看到的，下面一行初始化ORM，以便使用外部数据库连接<code>fProperties</code>通过SQL访问<code>TSQLRecordPeopleExt</code>数据：</p>
<pre><code class="lang-pascal hljs">VirtualTableExternalRegister(fExternalModel,TSQLRecordPeopleExt,fProperties,<span class="hljs-string">'PeopleExternal'</span>);
</code></pre>
<p>  我们还定制了外部表的名称，将默认的<code>'PeopleExt'</code>（通过从<code>TSQLRecordPeopleExt</code>去掉<code>TSQLRecord</code>前缀）改为<code>'PeopleExternal'</code>。</p>
<p>  除了映射表名之外，ORM还能够将<code>TSQLRecord</code>的发布属性名映射为数据库的各种自定义列名。实际上，现有数据库的很多表没有显式的列名是非常普遍的，当直接映射为TSQLRecord属性名时，这听起来可能非常奇怪，甚至已有数据库的主键与ORM将其命名为<code>ID</code>的要求也不尽一致。</p>
<p>  默认情况下，对于代码驱动的方法，内部属性名称将与外部表列名匹配，请参见<a href="">TSQLRecordPeopleExt代码优先的字段/列映射</a>。</p>
<p>  您可以对默认映射进行定制，例如：</p>
<pre><code class="lang-pascal hljs">fProperties := TSQLDBSQLite3ConnectionProperties.Create(SQLITE_MEMORY_DATABASE_NAME,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
VirtualTableExternalRegister(fExternalModel,TSQLRecordPeopleExt,fProperties,<span class="hljs-string">'PeopleExternal'</span>);
fExternalModel.Props[TSQLRecordPeopleExt].ExternalDB.
  MapField(<span class="hljs-string">'ID'</span>,<span class="hljs-string">'Key'</span>).
  MapField(<span class="hljs-string">'YearOfDeath'</span>,<span class="hljs-string">'YOD'</span>);
 (...) <span class="hljs-comment">// the remaining code stays the same</span>
</code></pre>
<p>  作为替代，您可以使用更简洁的<code>VirtualTableExternalMap</code>函数接口：</p>
<pre><code class="lang-pascal hljs">fProperties := TSQLDBSQLite3ConnectionProperties.Create(SQLITE_MEMORY_DATABASE_NAME,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
VirtualTableExternalMap(fExternalModel,TSQLRecordPeopleExt,fProperties,<span class="hljs-string">'PeopleExternal'</span>).
  MapField(<span class="hljs-string">'ID'</span>,<span class="hljs-string">'Key'</span>).
  MapField(<span class="hljs-string">'YearOfDeath'</span>,<span class="hljs-string">'YOD'</span>);
</code></pre>
<p>  之后像平常一样在Delphi代码中使用<code>TSQLRecordPeopleExt</code>表，包含<code>ID</code>和<code>YearOfDeath</code>字段。</p>
<p>  但在底层，mORMot ORM将在创建所有需要的SQL语句时进行映射：</p>
<ul>
<li>“内部”<code>TSQLRecord</code>类将存储在PeopleExternal外部表中；</li>
<li>“内部”<code>TSQLRecord.ID</code>字段将是一个外部<code>“Key: INTEGER”</code>列；</li>
<li>“内部<code>”TSQLRecord.YearOfDeath</code>字段将是一个外部<code>“YOD: INTEGER”</code>列；</li>
<li>其他内部发布的属性将默认以相同的名称映射到外部列。</li>
</ul>
<p>  因此，结果映射如下:</p>
<div class="plantuml-diagram"><!--?xml version="1.0" encoding="UTF-8" standalone="no"?--><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentscripttype="application/ecmascript" contentstyletype="text/css" height="430px" preserveAspectRatio="none" style="width:235px;height:430px;" version="1.1" viewBox="0 0 235 430" width="235px" zoomAndPan="magnify" class="view-svg"><defs><filter height="300%" id="f1kdwrajwafbyl" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"></feGaussianBlur><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"></feColorMatrix><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"></feOffset><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"></feBlend></filter></defs><g><ellipse cx="115.7459" cy="95.5968" fill="#FEFECE" filter="url(#f1kdwrajwafbyl)" rx="108.7459" ry="87.5968" style="stroke: #A80036; stroke-width: 1.5;"></ellipse><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="47" x="92.2459" y="28.7355">ID : TID</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="42.2115" x2="189.2804" y1="31.8117" y2="31.8117"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="134" x="48.7459" y="51.8557">Data : TSQLRawBlob</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="17.9843" x2="213.5076" y1="58.9318" y2="58.9318"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="138" x="46.7459" y="78.9758">FirstName : RawUTF8</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="8.6475" x2="222.8444" y1="86.0519" y2="86.0519"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="137" x="47.2459" y="106.0959">LastName : RawUTF8</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="10.2113" x2="221.2806" y1="113.1721" y2="113.1721"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="130" x="50.7459" y="133.216">YearOfBirth : integer</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="23.221" x2="208.2709" y1="140.2922" y2="140.2922"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="125" x="53.2459" y="160.3361">YearOfDeath : word</text><ellipse cx="115.4276" cy="331.1421" fill="#FEFECE" filter="url(#f1kdwrajwafbyl)" rx="109.4276" ry="88.1421" style="stroke: #A80036; stroke-width: 1.5;"></ellipse><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="96" x="67.4276" y="270.7713">Key : INTEGER</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="33.2722" x2="197.5831" y1="273.8475" y2="273.8475"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="79" x="75.9276" y="293.8914">Data : BLOB</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="13.612" x2="217.2433" y1="300.9676" y2="300.9676"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="177" x="26.9276" y="321.0115">FirstName : NVARCHAR(40)</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="7.0657" x2="223.7896" y1="328.0877" y2="328.0877"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="176" x="27.4276" y="348.1317">LastName : NVARCHAR(40)</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="11.1577" x2="219.6976" y1="355.2078" y2="355.2078"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="146" x="42.4276" y="375.2518">YearOfBirth : INTEGER</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="27.3422" x2="203.5131" y1="382.328" y2="382.328"></line><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="102" x="64.4276" y="402.3719">YOD : INTEGER</text><!--MD5=[1aa3f81a3bd80cff712043234baebedb]
link UC1 to UC2--><path d="M115.5,183.115 C115.5,200.91 115.5,219.708 115.5,237.695 " fill="none" id="UC1->UC2" style="stroke: #A80036; stroke-width: 1.0;"></path><polygon fill="#A80036" points="115.5,242.746,119.5,233.746,115.5,237.746,111.5,233.746,115.5,242.746" style="stroke: #A80036; stroke-width: 1.0;"></polygon><!--MD5=[2e4c90bdcbda351cf09e5450e3f41244]
@startuml
usecase UC1 as "ID : TID
- -
Data : TSQLRawBlob
- -
FirstName : RawUTF8
- -
LastName : RawUTF8
- -
YearOfBirth : integer
- -
YearOfDeath : word“

usecase UC2 as "Key : INTEGER
- -
Data : BLOB
- -
FirstName : NVARCHAR(40)
- -
LastName : NVARCHAR(40)
- -
YearOfBirth : INTEGER
- -
YOD : INTEGER"


(UC1) - ->(UC2)
@enduml

PlantUML version 1.2019.12(Sun Nov 03 18:24:54 CST 2019)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Java Version: 13.0.1+9
Operating System: Windows 10
Default Encoding: GBK
Language: zh
Country: CN
--></g></svg></div>
<p>  注意，只有<code>ID</code>和<code>YearOfDeath</code>列名是定制的。</p>
<p>  由于SQLite3虚拟表的设计，以及目前mORMot内部构件，数据库主键必须是一个整数字段，以便按照ORM的要求进行映射。但是您可以通过<code>stored AS_UNIQUE</code>代码定义各种辅助键，如对文本字段。</p>
<h3 id="toc_40">8.3.4. 与遗留代码共享数据库<a class="vnote-anchor" href="#toc_40" data-anchor-icon="#"></a></h3>
<p>  您很可能必须基于现有的数据库，使用许多已经编写好的SQL语句来维护和发展遗留项目，请参阅<a href="">遗留代码和项目</a>。如您希望将mORMot用于新特性，添加移动或HTML客户端。</p>
<p>  在这种情况下，ORM高级特性（如ORM缓存或批处理）可能与遗留代码冲突，因为可能需要共享表。在处理这样一些项目时，这里有一些指导原则。</p>
<p>  为了详尽地说明这个问题，我们需要考虑每一个ORM CRUD操作。我们可能需要将它们分为三类：查询、插入和对现有数据的修改。</p>
<p>  关于ORM查询，即<code>Retrieve()</code>方法，ORM缓存可以根据表进行调优，您肯定缺少一些缓存，但请记住：</p>
<ul>
<li>
<p>您可以为该缓存设置一个“超时”周期，以便在大多数情况下仍可从中获益；</p>
</li>
<li>
<p>您在服务级有一个缓存，在客户级有另一个缓存，因此您可以对其进行优化，使其在客户端上不那么具有侵略性；</p>
</li>
<li>
<p>您可以根据每个ID优化ORM缓存，以便仍然可以缓存一些不太可能更改的项目。</p>
</li>
</ul>
<p>  关于ORM插入，即<code>Add()</code>或<code>BatchAdd()</code>方法，在使用外部引擎时，如果一些外部进程可能插入新行，请确保将<code>TSQLRestStorageExternal EngineAddUseSelectMaxID</code>属性设置为TRUE，以便手工计算下一个最大ID。</p>
<p>  但这仍然可能是一个问题，因为外部进程可能在ORM插入期间执行插入。</p>
<p>  因此，最好不要使用ORM Add()或BatchAdd()方法，而是依赖于专用的INSERT SQL语句，如托管在服务端基于接口的服务中。</p>
<p>  关于ORM修改，即<code>Update() Delete() BatchUpdate() BatchDelete()</code>方法，它们听起来很安全，可以与修改数据库的外部进程一起使用，只要您使用事务使修改成为原子的，并且不会与遗留代码中的任何并发修改冲突。</p>
<p>  在处理一些遗留代码将在后台修改的外部表时，可能更安全的模式是绕过这些ORM方法，并定义基于服务端接口的服务。这些服务可能包含手动SQL，而不是使用神奇的ORM。但是这将取决于您的业务逻辑，并且您将无法从框架的ORM特性中获益。</p>
<p>  然而，在应用程序中引入面向服务的体系结构（SOA）将非常有益：ORM不是强制性的，特别是如果您熟悉SQL查询，知道如何使它们尽可能地标准化，拥有大量遗留代码，并且可能已经调优了SQL语句。</p>
<p>  要将新的客户端（如移动应用程序或AJAX现代站点）接入到应用程序，必须引入SOA。公平地说，您不应该再直接访问数据库，就像以前使用Delphi应用程序和RAD DB组件那样。</p>
<p>  所有新特性，包括用于存储新数据的新表，仍然受益于mORMot的ORM，并且仍然可以托管在相同的外部数据库中，与现有代码共享。</p>
<p>  然后，您将能够在遗留代码中识别<em>seam</em>（请参阅<a href="">遗留代码和项目</a>），并将它们移动到新的mORMot服务中，然后让您的应用程序演化为新的SOA/MVC体系结构，而不会破坏任何东西，也不会从头开始。</p>
<h3 id="toc_41">8.3.5. 自动映射SQL冲突字段名称<a class="vnote-anchor" href="#toc_41" data-anchor-icon="#"></a></h3>
<p>  如果应用程序可能运行在多个数据库上，那么从一个引擎切换到另一个引擎时，可能很难处理各种潜在的字段名称冲突。因此，ORM将确保没有字段名与底层数据库的SQL关键字冲突。</p>
<p>  在代码优先模式下，您可以使用以下方法来确保不会发生这种冲突：</p>
<pre><code class="lang-pascal hljs">fExternalModel.Props[TSQLRecordPeopleExt].ExternalDB.MapAutoKeywordFields;
</code></pre>
<p>  对于数据库优先的数据库，将使用以下语法来检查字段名:</p>
<pre><code class="lang-pascal hljs">fExternalModel.Props[TSQLRecordPeopleExt].ExternalDB. <span class="hljs-comment">// custom field mapping</span>
    MapField(<span class="hljs-string">'ID'</span>,<span class="hljs-string">'Key'</span>).
    MapField(<span class="hljs-string">'YearOfDeath'</span>,<span class="hljs-string">'YOD'</span>).
    MapAutoKeywordFields;
</code></pre>
<p>  或者使用简洁完整的接口定义：</p>
<pre><code class="lang-pascal hljs">VirtualTableExternalMap(fExternalModel,TSQLRecordPeopleExt,fProperties,<span class="hljs-string">'PeopleExternal'</span>).
    MapField(<span class="hljs-string">'ID'</span>,<span class="hljs-string">'Key'</span>).
    MapField(<span class="hljs-string">'YearOfDeath'</span>,<span class="hljs-string">'YOD'</span>).
    MapAutoKeywordFields
</code></pre>
<p>  对于数据库优先的数据库，在任何手动字段映射之后调用<code>MapAutoKeywordFields</code>方法是一个好主意，因为即使是自定义字段名称也可能与SQL关键字冲突。</p>
<p>  如果一些字段名可能与SQL关键字冲突，那么它将映射为后跟<code>'_'</code>。如<code>'Select'</code>发布属性将映射为表中的<code>SELECT_</code>列。</p>
<p>  即使这个选项默认情况下是禁用的，日志中也会出现一条警告消息，建议使用这个<code>MapAutoKeywordFields</code>方法，以帮助您识别此类问题。</p>
<h3 id="toc_42">8.3.6. ORM处理外部数据库<a class="vnote-anchor" href="#toc_42" data-anchor-icon="#"></a></h3>
<p>  <code>mORMotDB.pas</code>单元为框架基于<code>SynDB.pas</code>的外部数据库实现虚拟表访问。</p>
<p>  实际上，这个特性将使用<code>TSQLRestStorageExternal</code>、<code>TSQLVirtualTableCursorExternal</code>和<code>TSQLVirtualTableExternal</code>类，定义如下：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-20" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 830 292" style="max-width:830px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-20 .node&gt;rect { ; }
#mermaid-diagram-20 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-20 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-20 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-20 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M138.5,64L138.5,89L138.5,114" marker-end="url(#arrowhead1313)" style="fill:none"></path><defs><marker id="arrowhead1313" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M138.5,158L138.5,183L138.5,208" marker-end="url(#arrowhead1314)" style="fill:none"></path><defs><marker id="arrowhead1314" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M427,64L427,89L427,114" marker-end="url(#arrowhead1315)" style="fill:none"></path><defs><marker id="arrowhead1315" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M693.5,64L693.5,89L693.5,114" marker-end="url(#arrowhead1316)" style="fill:none"></path><defs><marker id="arrowhead1316" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A1" transform="translate(138.5,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-118.5" y="-22" width="237" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-108.5,-12)"><foreignObject width="217" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRecordVirtualTableAutoID</div></foreignObject></g></g></g><g class="node cyan" id="A2" transform="translate(138.5,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-75.5" y="-22" width="151" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-65.5,-12)"><foreignObject width="131" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRecordVirtual</div></foreignObject></g></g></g><g class="node cyan" id="A3" transform="translate(138.5,230)" style="opacity: 1;"><rect rx="0" ry="0" x="-52.5" y="-22" width="105" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-42.5,-12)"><foreignObject width="85" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRecord</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(427,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-120" y="-22" width="240" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-110,-12)"><foreignObject width="220" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLVirtualTableCursorExternal</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(427,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-92" y="-22" width="184" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-82,-12)"><foreignObject width="164" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLVirtualTableCursor</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(693.5,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-96.5" y="-22" width="193" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-86.5,-12)"><foreignObject width="173" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLVirtualTableExternal</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(693.5,136)" style="opacity: 1;"><rect rx="0" ry="0" x="-68.5" y="-22" width="137" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-58.5,-12)"><foreignObject width="117" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLVirtualTable</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  类的注册是通过调用以下新的全局过程完成的：</p>
<pre><code class="lang-pascal hljs"><span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">VirtualTableExternalRegister</span><span class="hljs-params">(aModel: TSQLModel; aClass: TSQLRecordClass;
  aExternalDB: TSQLDBConnectionProperties; <span class="hljs-keyword">const</span> aExternalTableName: RawUTF8)</span>;</span>
</code></pre>
<p>  该程序将在服务器端为ORM类注册一个外部数据库：</p>
<ul>
<li>它将定义提供的类的行为，类似于<code>TSQLRecordVirtualTableAutoID</code>类(如在这个ORM模型中，<code>TSQLModelRecordProperties.Kind</code>属性将被覆写为<code>rCustomAutoID</code>；</li>
<li>它将提供的类与<code>TSQLVirtualTableExternal</code>模块关联；</li>
<li><code>TSQLDBConnectionProperties</code>实例应该由所有类共享，并在ORM不再需要时全局释放；</li>
<li>正如外部数据库所希望的那样，这里应该提供完整的表名（当通过关联的SQLite3虚拟表调用时，<code>SQLTableName</code>将在内部用作表名），如果没有指定表名(")，将使用<code>SQLTableName</code>（如名为<code>TSQLCustomer</code>的类，使用<code>'Customer'</code>）；</li>
<li>内部动态地将SQL从内部ORM表示转换为外部SQL需要的格式（如表名或ID属性），请参见<code>TSQLRestStorage.AdaptSQLForEngineList</code>方法。</li>
</ul>
<p>  典型用法如下：</p>
<pre><code class="lang-pascal hljs">aProps := TOleDBMSSQLConnectionProperties.Create(<span class="hljs-string">'.\SQLEXPRESS'</span>,<span class="hljs-string">'AdventureWorks2008R2'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
aModel := TSQLModel.Create([TSQLCustomer],<span class="hljs-string">'root'</span>);
VirtualTableExternalRegister(aModel,TSQLCustomer,aProps,<span class="hljs-string">'Sales.Customer'</span>);
aServer := TSQLRestServerDB.Create(aModel,<span class="hljs-string">'application.db'</span>),true)
</code></pre>
<p>  如<a href="">对象关系映射</a>所述，其余所有代码将使用普通ORM类、方法和函数。</p>
<p>  为了存储在外部数据库中，ORM记录可以从各种<code>TSQLRecord</code>类继承。即使这个类没有从<code>TSQLRecordVirtualTableAutoID</code>继承，一旦为该类调用了<code>VirtualTableExternalRegister</code>函数，它也会这样做。</p>
<p>  与任何普通的<code>TSQLRecord</code>类一样，ORM核心希望外部表映射一个<code>Integer ID</code>发布属性，在每次插入记录时自动递增。由于并非所有数据库都处理此类字段，如Oracle自动增量将通过在初始化时执行<code>select max(id) from tablename</code>语句处理，然后通过线程安全缓存动态计算新插入使用的RowID。</p>
<p>  您不必知道数据持久性存储在哪里以及如何存储，框架将为您完成所有底层的数据库工作。由于SQlite3的虚拟表特性，内部和外部表可以在SQL语句中混合使用。根据实现需要，类可以通过内部SQLite3引擎或通过外部数据库持久化，只需在服务端初始化之前调用<code>VirtualTableExternalRegister()</code>即可。</p>
<p>  实际上，<code>TSQLVirtualTableCursorExternal</code>会根据外部数据库已有的索引，将外部表上的任何查询转换为正确优化的SQL查询。<code>TSQLVirtualTableExternal</code>还将把SQLite3级上的单个SQL修改语句（如insert / update / delete）转换为外部数据库的远程SQL语句。</p>
<p>  大多数情况下，所有RESTful方法（GET/POST/PUT/DELETE）都将由<code>TSQLRestStorageExternal</code>类直接处理，不会使用虚拟表机制。在实践中，对外部数据库的大多数访问都与直接访问一样快，但是虚拟表总是能够解释任何跨数据库的复杂请求或语句。</p>
<p>  直接REST访问将按照以下方式处理，如添加对象时：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-21" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 617 600" style="max-width:617px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-21 .node&gt;rect { ; }
#mermaid-diagram-21 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-21 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-21 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-21 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M247.02710843373495,64L135.5,125L135.5,186" marker-end="url(#arrowhead1348)" style="fill:none"></path><defs><marker id="arrowhead1348" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M327.47289156626505,64L439,125L439,186" marker-end="url(#arrowhead1349)" style="fill:none"></path><defs><marker id="arrowhead1349" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M135.5,230L135.5,267L135.5,304" marker-end="url(#arrowhead1350)" style="fill:none"></path><defs><marker id="arrowhead1350" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M135.5,348L135.5,385L135.5,422" marker-end="url(#arrowhead1351)" style="fill:none"></path><defs><marker id="arrowhead1351" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M135.5,466L135.5,491L135.5,516" marker-end="url(#arrowhead1352)" style="fill:none"></path><defs><marker id="arrowhead1352" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M439,230L439,267L439,304" marker-end="url(#arrowhead1353)" style="fill:none"></path><defs><marker id="arrowhead1353" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M439,348L439,385L439,422" marker-end="url(#arrowhead1354)" style="fill:none"></path><defs><marker id="arrowhead1354" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M439,466L439,491L439,516" marker-end="url(#arrowhead1355)" style="fill:none"></path><defs><marker id="arrowhead1355" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="translate(135.5,125)" style="opacity: 1;"><g transform="translate(-26.5,-24)" class="label"><foreignObject width="53" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">internal<br>table</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(439,125)" style="opacity: 1;"><g transform="translate(-28,-36)" class="label"><foreignObject width="56" height="72"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">external<br>table<br>REST</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(135.5,267)" style="opacity: 1;"><g transform="translate(-50.5,-12)" class="label"><foreignObject width="101" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">INSERT INTO...</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(135.5,385)" style="opacity: 1;"><g transform="translate(-53,-12)" class="label"><foreignObject width="106" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">internal engine</span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(439,267)" style="opacity: 1;"><g transform="translate(-50.5,-12)" class="label"><foreignObject width="101" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">INSERT INTO...</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(439,385)" style="opacity: 1;"><g transform="translate(-74.5,-12)" class="label"><foreignObject width="149" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">ODBC/ZDBC/OleDB...</span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A" transform="translate(287.25,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-91.5" y="-22" width="183" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-81.5,-12)"><foreignObject width="163" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRestServerDB.Add</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(135.5,208)" style="opacity: 1;"><rect rx="0" ry="0" x="-115.5" y="-22" width="231" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-105.5,-12)"><foreignObject width="211" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRestServerDB.EngineAdd</div></foreignObject></g></g></g><g class="node cyan" id="C1" transform="translate(439,208)" style="opacity: 1;"><rect rx="0" ry="0" x="-138" y="-22" width="276" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-128,-12)"><foreignObject width="256" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRestStorageExternal.EngineAdd</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(135.5,326)" style="opacity: 1;"><rect rx="0" ry="0" x="-56.5" y="-22" width="113" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-46.5,-12)"><foreignObject width="93" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRequest</div></foreignObject></g></g></g><g class="node cyan" id="B3" transform="translate(135.5,444)" style="opacity: 1;"><rect rx="0" ry="0" x="-61.5" y="-22" width="123" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-51.5,-12)"><foreignObject width="103" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQlite3 engine</div></foreignObject></g></g></g><g class="node cyan" id="B4" transform="translate(135.5,538)" style="opacity: 1;"><rect rx="0" ry="0" x="-50" y="-22" width="100" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-40,-12)"><foreignObject width="80" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQLite3 file</div></foreignObject></g></g></g><g class="node cyan" id="C2" transform="translate(439,326)" style="opacity: 1;"><rect rx="0" ry="0" x="-72.5" y="-22" width="145" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-62.5,-12)"><foreignObject width="125" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ISQLDBStatement</div></foreignObject></g></g></g><g class="node cyan" id="C3" transform="translate(439,444)" style="opacity: 1;"><rect rx="0" ry="0" x="-71.5" y="-22" width="143" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-61.5,-12)"><foreignObject width="123" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">External DB client</div></foreignObject></g></g></g><g class="node cyan" id="C4" transform="translate(439,538)" style="opacity: 1;"><rect rx="0" ry="0" x="-73.5" y="-22" width="147" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-63.5,-12)"><foreignObject width="127" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">External DB server</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  通过虚拟表的间接访问将处理如下：</p>
<div class="mermaid-diagram"><svg id="mermaid-diagram-22" xmlns="http://www.w3.org/2000/svg" height="100%" viewBox="0 0 442 954" style="max-width:442px;"><style type="text/css" title="mermaid-svg-internal-css">/*  */
#mermaid-diagram-22 .node&gt;rect { ; }
#mermaid-diagram-22 .node text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-22 .edgeLabel text  { fill:#000; stroke:none; font-weight:300; font-family:"Helvetica Neue",Helvetica,Arial,sans-serf; font-size:14px; }
#mermaid-diagram-22 .cluster rect  { rx:4px; fill: rgb(255, 255, 222); rx: 4px; stroke: rgb(170, 170, 51); stroke-width: 1px; }
#mermaid-diagram-22 .cyan&gt;rect, .cyan&gt;polygon, .cyan&gt;circle, .cyan&gt;ellipse { fill:#9ff;  stroke:#fff; }
/*  */
</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M176,64L176,113L176,162" marker-end="url(#arrowhead1400)" style="fill:none"></path><defs><marker id="arrowhead1400" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M176,206L176,243L176,280" marker-end="url(#arrowhead1401)" style="fill:none"></path><defs><marker id="arrowhead1401" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M176,324L176,361L176,398" marker-end="url(#arrowhead1402)" style="fill:none"></path><defs><marker id="arrowhead1402" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M142.53521126760563,442L68,491L68,540" marker-end="url(#arrowhead1403)" style="fill:none"></path><defs><marker id="arrowhead1403" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M209.46478873239437,442L284,491L284,540" marker-end="url(#arrowhead1404)" style="fill:none"></path><defs><marker id="arrowhead1404" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M284,584L284,621L284,658" marker-end="url(#arrowhead1405)" style="fill:none"></path><defs><marker id="arrowhead1405" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M284,702L284,739L284,776" marker-end="url(#arrowhead1406)" style="fill:none"></path><defs><marker id="arrowhead1406" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M284,820L284,845L284,870" marker-end="url(#arrowhead1407)" style="fill:none"></path><defs><marker id="arrowhead1407" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="translate(176,113)" style="opacity: 1;"><g transform="translate(-48,-24)" class="label"><foreignObject width="96" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">internal or<br>external table</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(176,243)" style="opacity: 1;"><g transform="translate(-50.5,-12)" class="label"><foreignObject width="101" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">INSERT INTO...</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(176,361)" style="opacity: 1;"><g transform="translate(-53,-12)" class="label"><foreignObject width="106" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">internal engine</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(68,491)" style="opacity: 1;"><g transform="translate(-26.5,-24)" class="label"><foreignObject width="53" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">internal<br>table</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(284,491)" style="opacity: 1;"><g transform="translate(-28,-24)" class="label"><foreignObject width="56" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">external<br>table</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(284,621)" style="opacity: 1;"><g transform="translate(-50.5,-12)" class="label"><foreignObject width="101" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">INSERT INTO...</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(284,739)" style="opacity: 1;"><g transform="translate(-74.5,-12)" class="label"><foreignObject width="149" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">ODBC/ZDBC/OleDB...</span></div></foreignObject></g></g><g class="edgeLabel" transform="" style="opacity: 1;"><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node cyan" id="A1" transform="translate(176,42)" style="opacity: 1;"><rect rx="0" ry="0" x="-91.5" y="-22" width="183" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-81.5,-12)"><foreignObject width="163" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRestServerDB.Add</div></foreignObject></g></g></g><g class="node cyan" id="A2" transform="translate(176,184)" style="opacity: 1;"><rect rx="0" ry="0" x="-115.5" y="-22" width="231" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-105.5,-12)"><foreignObject width="211" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRestServerDB.EngineAdd</div></foreignObject></g></g></g><g class="node cyan" id="A3" transform="translate(176,302)" style="opacity: 1;"><rect rx="0" ry="0" x="-56.5" y="-22" width="113" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-46.5,-12)"><foreignObject width="93" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLRequest</div></foreignObject></g></g></g><g class="node cyan" id="A4" transform="translate(176,420)" style="opacity: 1;"><rect rx="0" ry="0" x="-61.5" y="-22" width="123" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-51.5,-12)"><foreignObject width="103" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQlite3 engine</div></foreignObject></g></g></g><g class="node cyan" id="A5" transform="translate(68,562)" style="opacity: 1;"><rect rx="0" ry="0" x="-48" y="-22" width="96" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-38,-12)"><foreignObject width="76" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">SQlite3 file</div></foreignObject></g></g></g><g class="node cyan" id="B1" transform="translate(284,562)" style="opacity: 1;"><rect rx="0" ry="0" x="-118" y="-22" width="236" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-108,-12)"><foreignObject width="216" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">TSQLVirtualTableExternal.Insert</div></foreignObject></g></g></g><g class="node cyan" id="B2" transform="translate(284,680)" style="opacity: 1;"><rect rx="0" ry="0" x="-72.5" y="-22" width="145" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-62.5,-12)"><foreignObject width="125" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">ISQLDBStatement</div></foreignObject></g></g></g><g class="node cyan" id="B3" transform="translate(284,798)" style="opacity: 1;"><rect rx="0" ry="0" x="-71.5" y="-22" width="143" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-61.5,-12)"><foreignObject width="123" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">External DB client</div></foreignObject></g></g></g><g class="node cyan" id="B4" transform="translate(284,892)" style="opacity: 1;"><rect rx="0" ry="0" x="-73.5" y="-22" width="147" height="44"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-63.5,-12)"><foreignObject width="127" height="24"><div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">External DB server</div></foreignObject></g></g></g></g></g></g></svg></div>
<p>  关于速度，这里是回归测试日志文件的摘录（见前一段的代码），它显示了RESTful调用和虚拟表调用之间的区别，处理超过11,000行数据：</p>
<pre><code class="hljs">  - External via REST: 133,666 assertions passed  409.82ms
  - External via virtual table: 133,666 assertions passed  1.12s
</code></pre>
<p>  第一次运行使用<code>TSQLRestServer.StaticVirtualTableDirect</code>设置为TRUE（这是默认设置），也就是说，它将直接调用<code>TSQLRestStorageExternal</code>来执行RESTful命令；第二次将把这个属性设置为FALSE，也就是说，它将调用SQLite3引擎，并通过虚拟表机制将其转换为另一个SQL调用。</p>
<p>  值得指出的是，该测试使用内存SQLite3数据库（即通过<code>SQLITE_MEMORY_DATABASE_NAME</code>伪文件名实例化）作为外部数据库，因此我们在这里测试的主要是ORM开销，而不是外部数据库速度。对于真正的基于文件或远程数据库（如MS SQL），远程连接的开销远远大于虚拟表的使用。</p>
<p>  在所有情况下，默认的<code>StaticVirtualTableDirect=true</code>将确保最佳性能。正如<a href="">数据访问基准测试</a>所述，使用虚拟或直接调用不会影响CRUD操作速度：只要可能，它将绕过虚拟引擎。</p>
<h3 id="toc_43">8.3.7. 进程优化<a class="vnote-anchor" href="#toc_43" data-anchor-icon="#"></a></h3>
<p>  下面将详细介绍服务端的多线程能力以及所有可用的设置。</p>
<p>  默认情况下，所有ORM读操作将在并发模式下运行，所有ORM写操作将在阻塞模式下执行。所以使用我们的内部SQLite3引擎或大多数外部数据库，既安全又快速。但您可能需要更改此默认行为，具体取决于所连接的外部引擎。</p>
<p>  通常<code>TSQLDBConnectionProperties</code>将从<code>TSQLDBConnectionPropertiesThreadSafe</code>继承，因此将为每个连接创建一个线程，这是有效的，但是一些驱动可能会有问题。</p>
<p>  首先，一些数据库客户端库可能不允许在多个线程之间共享事务，如MS SQL。其他客户端可能会为每个连接消耗大量资源，或者可能没有良好的多线程伸缩能力。有些数据库服务端确实为每个连接的客户端分配不同的进程，如PostgreSQL：您可能希望只使用一个连接来减少服务端资源，因此服务端只运行一个进程。为了避免这些问题，您可以强制所有ORM写操作在一个专用线程中执行，即通过设置<code>amMainThread</code>（这在没有UI的服务端不太合适），或者更好地通过<code>amBackgroundThread</code>或<code>amBackgroundORMSharedThread</code>：</p>
<pre><code class="lang-pascal hljs"> aServer.AcquireExecutionMode[execORMWrite] := amBackgroundThread;
</code></pre>
<p>  其次，特别是在长时间运行的n层mORMot服务端，可能会出现连接异常中断。如一个晚上没有任何活动之后，对外部数据库的访问可能在早上失败，因为数据库服务器可能断开了连接。</p>
<p>  您可以使用<code>TSQLDBConnectionProperties.ConnectionTimeOutMinutes</code>属性指定最大不活动时间，在此之后将刷新和重新创建所有连接，以避免潜在的断开连接问题。</p>
<p>  在实践中，在一段时间后重新创建连接是安全的，不会减慢进程，相反，它可能有助于减少消耗的资源，并稳定长时间运行的n层服务器。</p>
<p>  <code>ThreadSafeConnection</code>方法将检查其<code>TSQLDBConnectionProperties</code>实例上的最后一个活动，然后调用<code>ClearConnectionPool</code>，以便在空闲时间过长时释放所有活动连接。</p>
<p>  因此，如果您使用<code>ConnectionTimeOutMinutes</code>属性，您应该确保后台没有其他连接仍然处于活动状态，否则可能会发生一些意外问题。</p>
<p>  例如，您应该确保您的mORMot ORM服务器在读写的阻塞模式下运行所有语句:</p>
<pre><code class="lang-pascal hljs">aServer.AcquireExecutionMode[execORMGet] := am***;
 aServer.AcquireExecutionMode[execORMWrite] := am***;
</code></pre>
<p>  在这里，安全阻塞<code>am***</code>模式是除<code>amunlock</code>外的任何模式，即<code>amLocked</code>、<code>amBackgroundThread</code>、<code>amBackgroundORMSharedThread</code>或<code>amMainThread</code>。</p>

    </div>
</div>
</div>

<div id="container-floating" style="display:none;" class="d-none d-md-block d-xl-block">
    <div id="floating-button" onclick="toggleMore()">
        <p id="floating-more" class="more">&gt;</p>
    </div>
</div>

<!--
<div class="footer" id="vnote-footer">
    <p>Generated by <em><a href="https://tamlok.github.io/vnote/">VNote</a></em>.</p>
</div>
-->
</body>
</html>
